1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
   | struct SegTree {     struct data {         ll minv, cnt;     };       struct lztag {         int v;     };     typedef data T;     typedef int Lz;
      #define M ((L+R)>>1)
      int LEFT, RIGHT;       vector<T> sumv; 
      vector<Lz> tag;      vector<int> ls, rs;     vector<int> raw;           T add(T a, T b,int L, int R) {            if (a.minv == b.minv) return {a.minv, a.cnt + b.cnt};         if (a.minv < b.minv) return {a.minv, a.cnt + raw[R]-raw[M]};         return {b.minv, b.cnt + raw[M]-raw[L-1]};     }      T addt(T a, Lz b, int o, int l, int r) {          a.minv += b;          return a;     }     Lz addtt (Lz a, Lz b) {          return a + b;     }
      T zeroT = {0,0};     Lz zeroLz = 0;           SegTree(int left, int right) : LEFT(left), RIGHT(right), sumv(1), tag(1), ls(1), rs(1) {}     SegTree(vector<int>& raw) : LEFT(1), RIGHT(sz(raw)-1), sumv(1), tag(1), ls(1), rs(1), raw(raw) {}
      inline int getpos(int x) {         return lower_bound(raw.begin(), raw.end(), x) - raw.begin();     }
      inline void pushdown(int o, int L, int R) {         if (L != R && !ls[o]) newnode(o);          if (L == R || tag[o] == zeroLz) return;         sumv[ls[o]] = addt(sumv[ls[o]], tag[o],o, L, M);         sumv[rs[o]] = addt(sumv[rs[o]], tag[o],o, M+1, R);         tag[ls[o]] = addtt(tag[ls[o]], tag[o]);         tag[rs[o]] = addtt(tag[rs[o]], tag[o]);         tag[o] = zeroLz;      }
      void newnode(int o) {         sumv.push_back(zeroT); sumv.push_back(zeroT);         tag.push_back(zeroLz); tag.push_back(zeroLz);         ls.push_back(0); ls.push_back(0);         rs.push_back(0); rs.push_back(0);         ls[o] = sz(sumv)-2; rs[o] = sz(sumv)-1;     }
      inline void insert(int x, Lz val, int o=0, int L=1, int R=-1) {         if (R == -1) {L = LEFT; R = RIGHT; x = getpos(x); }         if (L == R) sumv[o] = addt(sumv[o], val,o, L, R);         else {             pushdown(o, L, R);             if (x <= M) insert(x, val, ls[o], L, M);             else insert(x, val, rs[o], M+1, R);             sumv[o] = add(sumv[ls[o]], sumv[rs[o]],L,R);         }     }
      inline void update(int x, int y, Lz val, int o=0, int L=1, int R=-1) {         if (R == -1) {L = LEFT; R = RIGHT; if (!raw.empty()) x = getpos(x)+1, y = getpos(y); }         if (x <= L && R <= y) sumv[o] = addt(sumv[o], val,o, L, R), tag[o] = addtt(tag[o], val);         else {             pushdown(o, L, R);             if (x <= M) update(x, y, val, ls[o], L, M);             if (y > M) update(x, y, val, rs[o], M+1, R);             sumv[o] = add(sumv[ls[o]], sumv[rs[o]],L,R);          }     }
      inline T query(int x=-1, int y=-1, int o=0, int L=1, int R=-1) {         if (R == -1) {L = LEFT; R = RIGHT; if (x==-1) x=LEFT,y=RIGHT; else if (!raw.empty()) x = getpos(x)+1, y = getpos(y); }         pushdown(o, L, R);         if (x <= L && R <= y) return sumv[o];         else if (x <= M && y > M) return add(query(x, M, ls[o], L, M), query(M+1, y, rs[o], M+1, R),L,R);         else if (x <= M)  return query(x, y, ls[o], L, M);         else return query(x, y, rs[o], M+1, R);      } };
  ll sweepline(vector<tuple<int,int,int,int>>& A) {     struct Line {         ll y1, y2, x, k;         bool operator<(const Line& l) const {             if (x == l.x) return k > l.k;             return x < l.x;          }     };     vector<Line> v;      vector<int> B;      for (auto [x1,y1,x2,y2] : A) {         v.push_back({y1,y2,x1,1});         v.push_back({y1,y2,x2,-1});         B.push_back(y1);         B.push_back(y2);     }     sort(v.begin(), v.end());     sort(B.begin(), B.end());     int nm = unique(B.begin(), B.end()) - B.begin();      while (sz(B) != nm) B.pop_back();     SegTree seg(B);     ll prex = 0;     ll ans = 0;     for (auto [y1,y2,x,k] : v) {         auto [minv, cnt] = seg.query();         cnt = minv ? B.back()-B[0] : cnt;         ans += (x - prex)*cnt;         seg.update(y1,y2, k);         prex = x;     }     return ans; }
  |