Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdio>
- #include <cassert>
- #include <tuple>
- #include <vector>
- using namespace std;
- const int N = 1 << 19;
- vector<pair<int, int>> inc[N], dec[N];
- int n;
- vector<int> pos[N];
- inline void add_rect(int l1, int r1, int l2, int r2) {
- assert(0 <= l1 && l1 <= r1 && r1 <= l2 && l2 <= r2 && r2 <= n - 1);
- inc[l1].emplace_back(l2, r2);
- dec[r1].emplace_back(l2, r2);
- }
- void process(int x, const vector<int>& pos) {
- for (int i = 0; i + 2 < pos.size(); i++) {
- int l = pos[i] + 1;
- int r = pos[i + 1];
- int l2 = pos[i + 1];
- int r2 = (i + x < pos.size()) ? pos[i + x] - 1 : n - 1;
- if (x != 1)
- add_rect(l, r, l2, r2);
- if (i + x + 2 < pos.size()) {
- int l3 = pos[i + x + 1];
- int r3 = n - 1;
- add_rect(l, r, l3, r3);
- }
- }
- }
- int Tmn[2 * N], Tcnt[2 * N];
- int Tadd[2 * N];
- void add(int l, int r, int x, int L = 0, int R = N - 1, int v = 1) {
- if (r < L || l > R)
- return;
- if (l <= L && R <= r) {
- Tadd[v] += x;
- return;
- }
- add(l, r, x, L, (L + R) / 2, 2 * v);
- add(l, r, x, (L + R) / 2 + 1, R, 2 * v + 1);
- Tmn[v] = min(Tmn[2 * v] + Tadd[2 * v], Tmn[2 * v + 1] + Tadd[2 * v + 1]);
- Tcnt[v] = 0;
- if (Tmn[v] == Tmn[2 * v] + Tadd[2 * v])
- Tcnt[v] += Tcnt[2 * v];
- if (Tmn[v] == Tmn[2 * v + 1] + Tadd[2 * v + 1])
- Tcnt[v] += Tcnt[2 * v + 1];
- }
- pair<int, int> get(int l, int r, int L = 0, int R = N - 1, int v = 1) {
- if (r < L || l > R) {
- return make_pair(N + 42, -42);
- } else if (l <= L && R <= r) {
- return make_pair(Tmn[v] + Tadd[v], Tcnt[v]);
- } else {
- int mn1, cnt1, mn2, cnt2;
- tie(mn1, cnt1) = get(l, r, L, (L + R) / 2, 2 * v);
- tie(mn2, cnt2) = get(l, r, (L + R) / 2 + 1, R, 2 * v + 1);
- int mn = min(mn1, mn2);
- int cnt = 0;
- if (mn == mn1)
- cnt += cnt1;
- if (mn == mn2)
- cnt += cnt2;
- return make_pair(mn + Tadd[v], cnt);
- }
- }
- int main() {
- freopen("segments.in", "r", stdin);
- freopen("segments.out", "w", stdout);
- scanf("%d", &n);
- for (int i = N; i < 2 * N; i++)
- Tcnt[i] = 1;
- for (int i = N - 1; i > 0; i--)
- Tcnt[i] = Tcnt[2 * i] + Tcnt[2 * i + 1];
- for (int i = 0; i < n; i++) {
- int x;
- scanf("%d", &x);
- pos[x].push_back(i);
- }
- for (int i = 1; i <= n; i++) {
- if (pos[i].empty())
- continue;
- pos[i].insert(pos[i].begin(), -1);
- pos[i].insert(pos[i].end(), n);
- process(i, pos[i]);
- }
- long long ans = 0;
- for (int x = 0; x < n; x++) {
- for (auto seg : inc[x]) {
- add(seg.first, seg.second, 1);
- }
- int mn, cnt;
- tie(mn, cnt) = get(x, n - 1);
- ans += (mn == 0) ? cnt : 0;
- for (auto seg : dec[x]) {
- add(seg.first, seg.second, -1);
- }
- }
- printf("%lld\n", ans);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement