Advertisement
apoorv_me

Untitled

Dec 16th, 2024 (edited)
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.36 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #ifdef LOCAL
  5. #include "../debug.h"
  6. #else
  7. #define dbg(...)
  8. #endif
  9.  
  10.  
  11. template<class Info, class Tag>
  12. struct LazySegmentTree {
  13.     int n;
  14.     std::vector<Info> info;
  15.     std::vector<Tag> tag;
  16.     LazySegmentTree() : n(0) {}
  17.     LazySegmentTree(int n_, Info v_ = Info()) {
  18.         init(n_, v_);
  19.     }
  20.     template<class T>
  21.     LazySegmentTree(std::vector<T> init_) {
  22.         init(init_);
  23.     }
  24.     void init(int n_, Info v_ = Info()) {
  25.         init(std::vector(n_, v_));
  26.     }
  27.     template<class T>
  28.     void init(std::vector<T> init_) {
  29.         n = init_.size();
  30.         info.assign(4 << std::__lg(n), Info());
  31.         tag.assign(4 << std::__lg(n), Tag());
  32.         std::function<void(int, int, int)> build = [&](int p, int l, int r) {
  33.             if (r - l == 1) {
  34.                 info[p] = init_[l];
  35.                 return;
  36.             }
  37.             int m = (l + r) / 2;
  38.             build(2 * p, l, m);
  39.             build(2 * p + 1, m, r);
  40.             pull(p);
  41.         };
  42.         build(1, 0, n);
  43.     }
  44.     void pull(int p) {
  45.         info[p] = info[2 * p] + info[2 * p + 1];
  46.     }
  47.     void apply(int p, const Tag &v) {
  48.       if(v.add == -1) return;
  49.         info[p].apply(v);
  50.         tag[p].apply(v);
  51.     }
  52.     void push(int p) {
  53.         apply(2 * p, tag[p]);
  54.         apply(2 * p + 1, tag[p]);
  55.         tag[p] = Tag();
  56.     }
  57.  
  58.     void modify(int p, int l, int r, int x, const Info &v) {
  59.         if (r - l == 1) {
  60.             info[p] = v;
  61.             return;
  62.         }
  63.         int m = (l + r) / 2;
  64.         push(p);
  65.         if (x < m) {
  66.             modify(2 * p, l, m, x, v);
  67.         } else {
  68.             modify(2 * p + 1, m, r, x, v);
  69.         }
  70.         pull(p);
  71.     }
  72.     void modify(int p, const Info &v) {
  73.         modify(1, 0, n, p, v);
  74.     }
  75.     Info rangeQuery(int p, int l, int r, int x, int y) {
  76.         if (l >= y || r <= x) {
  77.             return Info();
  78.         }
  79.         if (l >= x && r <= y) {
  80.             return info[p];
  81.         }
  82.         int m = (l + r) / 2;
  83.         push(p);
  84.         return rangeQuery(2 * p, l, m, x, y) + rangeQuery(2 * p + 1, m, r, x, y);
  85.     }
  86.     Info rangeQuery(int l, int r) {
  87.         return rangeQuery(1, 0, n, l, r);
  88.     }
  89.     void rangeApply(int p, int l, int r, int x, int y, const Tag &v) {
  90.         if (l >= y || r <= x) {
  91.             return;
  92.         }
  93.         if (l >= x && r <= y) {
  94.             apply(p, v);
  95.             return;
  96.         }
  97.         int m = (l + r) / 2;
  98.         push(p);
  99.         rangeApply(2 * p, l, m, x, y, v);
  100.         rangeApply(2 * p + 1, m, r, x, y, v);
  101.         pull(p);
  102.     }
  103.     void rangeApply(int l, int r, const Tag &v) {
  104.         return rangeApply(1, 0, n, l, r, v);
  105.     }
  106.     template<class F>
  107.     int findFirst(int p, int l, int r, int x, int y, F &&pred) {
  108.         if (l >= y || r <= x) {
  109.             return -1;
  110.         }
  111.         if (l >= x && r <= y && !pred(info[p])) {
  112.             return -1;
  113.         }
  114.         if (r - l == 1) {
  115.             return l;
  116.         }
  117.         int m = (l + r) / 2;
  118.         push(p);
  119.         int res = findFirst(2 * p, l, m, x, y, pred);
  120.         if (res == -1) {
  121.             res = findFirst(2 * p + 1, m, r, x, y, pred);
  122.         }
  123.         return res;
  124.     }
  125.     template<class F>
  126.     int findFirst(int l, int r, F &&pred) {
  127.         return findFirst(1, 0, n, l, r, pred);
  128.     }
  129.     template<class F>
  130.     int findLast(int p, int l, int r, int x, int y, F &&pred) {
  131.         if (l >= y || r <= x) {
  132.             return -1;
  133.         }
  134.         if (l >= x && r <= y && !pred(info[p])) {
  135.             return -1;
  136.         }
  137.         if (r - l == 1) {
  138.             return l;
  139.         }
  140.         int m = (l + r) / 2;
  141.         push(p);
  142.         int res = findLast(2 * p + 1, m, r, x, y, pred);
  143.         if (res == -1) {
  144.             res = findLast(2 * p, l, m, x, y, pred);
  145.         }
  146.         return res;
  147.     }
  148.     template<class F>
  149.     int findLast(int l, int r, F &&pred) {
  150.         return findLast(1, 0, n, l, r, pred);
  151.     }
  152. };
  153.  
  154. struct Tag {
  155.     int add = -1;
  156.     void apply(Tag t) {
  157.         add = t.add;
  158.     }
  159. };
  160.  
  161. struct Info {
  162.     int64_t min = 0;
  163.     int sz;
  164.     Info(int mn = 0, int s = 1) {
  165.       min = mn;
  166.       sz = s;
  167.     }
  168.     void apply(Tag t) {
  169.         min = sz * 1ll * t.add;
  170.     }
  171. };
  172.  
  173. Info operator+(const Info &a, const Info &b) {
  174.     return {a.min + b.min, a.sz + b.sz};
  175. }
  176.  
  177. int32_t main() {
  178.   ios_base::sync_with_stdio(0);
  179.   cin.tie(0);
  180.  
  181.   auto __solve_testcase = [&](int test) {
  182.     int N;  cin >> N;
  183.     vector<int> A(N);
  184.     for(auto &a: A)
  185.       cin >> a;
  186.     set<int> gud; gud.insert(-1);
  187.     vector<int> pos(N + 1, -1);
  188.     LazySegmentTree<Info, Tag> segl(N), segr(N);
  189.     int64_t res = 0;
  190.     for(int i = 0 ; i < N ; ++i) {
  191.       segl.rangeApply(i, i + 1, Tag(i + 1));
  192.       segr.rangeApply(i, i + 1, Tag(i + 1));
  193.  
  194.       int v = A[i];
  195.       if(pos[v] >= 0) {
  196.         int in = *prev(gud.lower_bound(pos[v]));  gud.insert(pos[v]);
  197.         dbg(in, pos[v], v);
  198.         segl.rangeApply(in + 1, pos[v] + 1, Tag(pos[v]));
  199.         segr.rangeApply(0, pos[v] + 1, Tag(i + 1));
  200.       }
  201.       pos[v] = i;
  202.       res += segr.rangeQuery(0, i).min - segl.rangeQuery(0, i).min;
  203.     }
  204.     cout << res << '\n';
  205.   };
  206.  
  207.   int NumTest = 1;
  208.   cin >> NumTest;
  209.   for(int testno = 1; testno <= NumTest ; ++testno) {
  210.     __solve_testcase(testno);
  211.   }
  212.  
  213.   return 0;
  214. }
  215.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement