Manioc

sweep line fudida com segtree priquitin

Nov 15th, 2018
209
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.71 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define MAX 1000000007
  3.  
  4. using namespace std;
  5.  
  6. typedef long long ll;
  7. typedef long double ld;
  8. typedef pair<int, int> ii;
  9. typedef vector<int> vi;
  10.  
  11. template<typename T>
  12. void trace(T a) { cout << a << "\n";}
  13. template<typename T, typename... Args>
  14. void trace(T a, Args... args) { cout << a << " "; trace(args...);}
  15.  
  16. struct Q{
  17.     ll x, l, r;
  18.     bool end;
  19.     Q(ll _x, ll _l, ll _r, bool _end): x(_x), l(_l), r(_r), end(_end){}
  20. };
  21.  
  22. struct node;
  23. node *newNode();
  24.  
  25. struct node{
  26.   ll value;
  27.   bool lazy;
  28.   node *l, *r;
  29.  
  30.   node():value(0), l(NULL), r(NULL), lazy(0){}
  31.  
  32.   void expand(int a, int b){
  33.       if(!l) l = newNode();
  34.       if(!r) r = newNode();
  35.       if(lazy){
  36.           int mid = (a+b)/2;
  37.           l->doLazy(abs(mid-a+1-l->value));
  38.           r->doLazy(abs(mid-b-r->value));
  39.           lazy = lazy^1;
  40.       }
  41.   }
  42.  
  43.   void doLazy(int value){
  44.         lazy = lazy^1;
  45.         this->value = value;
  46.   }
  47.  
  48.   ll query(int a, int b, ll i, ll j){
  49.       if(i > b || j < a) return 0;
  50.       if(a >= i && b <= j) return value;
  51.       expand(a, b);
  52.       int mid = (a+b)/2;
  53.       return l->query(a, mid, i, j) + r->query(mid+1, b, i, j);
  54.   }
  55.  
  56.   void update(int a, int b, ll i, ll j){
  57.       if(i > b || j < a) return;
  58.       if(a >= i && b <= j) {
  59.           doLazy(abs(b-a+1-value));
  60.       }else{
  61.         expand(a, b);
  62.         int mid = (a+b)/2;
  63.         l->update(a, mid, i, j);
  64.         r->update(mid+1, b, i, j);
  65.  
  66.         value = l->value + r->value;
  67.       }
  68.   }
  69. };
  70.  
  71. node *newNode(){
  72.     static int bufSize = 1e7;
  73.     static node buf[(int)1e7];
  74.     assert(bufSize);
  75.     return &buf[--bufSize];
  76. }
  77. bool compare(Q a, Q b){
  78.     if(a.x == b.x) return a.end < b.end;
  79.     return a.x < b.x;
  80. }
  81.  
  82. int main(){
  83.     node *root = newNode();
  84.     int n; scanf("%d", &n);
  85.     vector<Q> que;
  86.  
  87.     for(int i = 0; i < n; i++){
  88.         int a, b, c, d;scanf("%d %d %d %d", &a, &b, &c, &d);
  89.         que.push_back(Q(a, b, d, false));
  90.         que.push_back(Q(c, b, d, true));
  91.     }
  92.  
  93.     sort(que.begin(), que.end(), compare);
  94.     ll ans = 0;
  95.     ll last = 0;
  96.     for(int i = 0; i < que.size();){
  97.         Q ac = que[i];
  98.         if(i) ans += last*(ac.x-que[i-1].x);
  99.  
  100.         ll past = que[i].x;
  101.         //trace("chegou ", ans, "-", root->value);
  102.         while(ac.x == past && !ac.end){
  103.             root->update(0, MAX, ac.l, ac.r-1);
  104.             past = ac.x;
  105.             ac = que[++i];
  106.         }
  107.         //ans += root->value;
  108.         while(ac.x == past){
  109.             root->update(0, MAX, ac.l, ac.r-1);
  110.             past = ac.x;
  111.             ac = que[++i];
  112.         }
  113.         //trace("saiu ", root->value);
  114.         last = root->value;
  115.     }
  116.     printf("%lld\n", ans);
  117.  
  118.     return 0;
  119. }
Advertisement
Add Comment
Please, Sign In to add comment