Advertisement
Guest User

acpc 2017 problem L tle

a guest
Aug 20th, 2017
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.08 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define ll long long
  5.  
  6. // use a segtree to store water level sum
  7. // O(n(logn)^2)
  8. struct Wall {
  9.     struct SegTree {
  10.         int length;
  11.         vector<ll> value;
  12.         bitset<400001> lazy;
  13.         void resize(const int& n) {
  14.             for (length = 1; length < n; length*=2);
  15.             value.resize(2*length);
  16.             //lazy.resize(2*length);
  17.             clear();
  18.         }
  19.         void clear() {
  20.             memset(&value[0], 0, 2*length*sizeof(value[0]));
  21.             //memset(&lazy[0], 0, length*sizeof(lazy[0]));
  22.             lazy.reset();
  23.         }
  24.         // lazy propagate happens only after overwrite so we can do this
  25.         void propagate(const int& i) {
  26.             value[2*i] = value[2*i+1] = value[i]/2;
  27.             lazy[2*i] = lazy[2*i+1] = true;
  28.             lazy[i] = false;
  29.         }
  30.         void increase(const int& x, const ll& h, const int& start, const int& end) {
  31.             // get index
  32.             const int i = (length+x-1)/(end-start+1);
  33.             if (start == end) {
  34.                 value[i] += h;
  35.                 return;
  36.             }
  37.             // lazy propagation
  38.             if (lazy[i]) propagate(i);
  39.             // update sum
  40.             value[i] += h;
  41.  
  42.             const int mid = (start+end-1)/2;
  43.             if (x <= mid) increase(x, h, start, mid);
  44.             else increase(x, h, mid+1, end);
  45.         }
  46.         void increase(const int& x, ll h) {
  47.             increase(x, h, 1, length);
  48.         }
  49.         void overwrite(const int& xl, const int& xr, const ll& h, const int& start, const int& end) {
  50.             // get index
  51.             const int i = (length+xl-1)/(end-start+1);
  52.             if (xl == start && xr == end) {
  53.                 value[i] = (xr-xl+1)*h;
  54.                 lazy[i] = true;
  55.                 return;
  56.             }
  57.             // no lazy propagation because overwrite
  58.             // update sum
  59.             value[i] += (xr-xl+1)*h - query(xl, xr);
  60.  
  61.             const int mid = (start+end-1)/2;
  62.             if (xr <= mid) overwrite(xl, xr, h, start, mid);
  63.             else if (xl > mid) overwrite(xl, xr, h, mid+1, end);
  64.             else {
  65.                 overwrite(xl, mid, h, start, mid);
  66.                 overwrite(mid+1, xr, h, mid+1, end);
  67.             }
  68.         }
  69.         void overwrite(const int& xl, const int& xr, ll h) {
  70.             if (xl > xr) overwrite(xr, xl, h, 1, length);
  71.             else overwrite(xl, xr, h, 1, length);
  72.         }
  73.         ll query(const int& xl, const int& xr, const int& start, const int& end) {
  74.             // get index
  75.             const int i = (length+xl-1)/(end-start+1);
  76.             if (xl == start && xr == end) {
  77.                 return value[i];
  78.             }
  79.             // lazy propagation
  80.             if (lazy[i]) propagate(i);
  81.  
  82.             const int mid = (start+end-1)/2;
  83.             if (xr <= mid) return query(xl, xr, start, mid);
  84.             else if (xl > mid) return query(xl, xr, mid+1, end);
  85.             else {
  86.                 return query(xl, mid, start, mid) + query(mid+1, xr, mid+1, end);
  87.             }
  88.         }
  89.         ll query(const int& xl, const int& xr) {
  90.             return query(xl, xr, 1, length);
  91.         }
  92.         ll query(const int& x) {
  93.             return query(x, x, 1, length);
  94.         }
  95.     };
  96.     SegTree water; // water level = max(height of water, height of wall)
  97.     int wallsum; // sum of blocks
  98.     vector<int> wallheight; // heights
  99.     // highest water level
  100.     int maxindex;
  101.     int maxheight;
  102.     Wall(const int& n) {
  103.         water.resize(n);
  104.         wallheight.resize(n+1);
  105.     }
  106.     void clear() {
  107.         water.clear();
  108.         memset(&wallheight[0], 0, wallheight.size()*sizeof(wallheight[0]));
  109.         wallsum = 0;
  110.         maxindex = 1;
  111.         maxheight = 0;
  112.     }
  113.     ll volume(const int& n) {
  114.         return water.query(1, n) - wallsum;
  115.     }
  116.     int searchinc(int left, int right, const int& upperbound) {
  117.         int mid;
  118.         while (left <= right) {
  119.             mid = (left+right)/2;
  120.             if (water.query(mid) > upperbound)
  121.                 right = mid-1;
  122.             else left = mid+1;
  123.         }
  124.         if (water.query(mid) > upperbound)
  125.             mid--;
  126.         return mid;
  127.     }
  128.     int searchdec(int left, int right, const int& upperbound) {
  129.         int mid;
  130.         while (left <= right) {
  131.             mid = (left+right)/2;
  132.             if (water.query(mid) > upperbound)
  133.                 left = mid+1;
  134.             else right = mid-1;
  135.         }
  136.         if (water.query(mid) > upperbound)
  137.             mid++;
  138.         return mid;
  139.     }
  140.     void insert(const int& i, const int& h) {
  141.         // get waterheight
  142.         const int waterheight = water.query(i);
  143.         // increase wall height
  144.         wallheight[i] += h;
  145.         wallsum += h;
  146.         // update water height
  147.         if (wallheight[i] > waterheight) {
  148.             if (wallheight[i] >= maxheight) {
  149.                 // new maximum
  150.                 // update everything between i and maxheight.first
  151.                 water.overwrite(i, maxindex, maxheight);
  152.                 water.overwrite(i, i, wallheight[i]);
  153.                 // update new max height
  154.                 maxindex = i;
  155.                 maxheight = wallheight[i];
  156.             }
  157.             else {
  158.                 // update everything between wallheight and next water level
  159.                 if (i < maxindex)
  160.                     water.overwrite(i, searchinc(i,maxindex,wallheight[i]), wallheight[i]);
  161.                 else
  162.                     water.overwrite(searchdec(maxindex,i,wallheight[i]), i, wallheight[i]);
  163.             }
  164.         }
  165.     }
  166. };
  167.  
  168. int main() {
  169.     //ios::sync_with_stdio(0);
  170.     cin.tie(0);
  171.  
  172.     Wall waterwall(100000);
  173.     int cols, queries, index, height;
  174.     char type;
  175.     int T;
  176.     scanf("%d", &T);
  177.     while (T--) {
  178.         waterwall.clear();
  179.         scanf("%d %d", &cols, &queries);
  180.         for (int i = 0; i < cols; i++) {
  181.             scanf("%d", &height);
  182.             waterwall.insert(i+1, height);
  183.         }
  184.         for (int i = 0; i < queries; i++) {
  185.             type = getchar();
  186.             while (isspace(type))
  187.                 type = getchar();
  188.             if (type == 'P') {
  189.                 printf("%d\n", waterwall.volume(cols));
  190.             }
  191.             else {
  192.                 scanf("%d %d", &index, &height);
  193.                 waterwall.insert(index, height);
  194.             }
  195.         }
  196.     }
  197.  
  198.     return 0;
  199. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement