Tarango

ADD MULTIPLICATION

Jul 8th, 2015
313
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.00 KB | None | 0 0
  1. //============================================================================
  2. // Name        : ACM
  3. // Author      : Tarango Khan
  4. // Copyright   : Team Byteheads
  5. // Description : !!!Hello World!!!
  6. //============================================================================
  7.  
  8. #include <bits/stdc++.h>
  9. using namespace std;
  10. #define inf 99999999
  11. #define Size 1000050
  12. #define Mod 1000000007
  13.  
  14. struct lazy {
  15.     int typ;
  16.     long long value;
  17.     int time;
  18.     lazy(int t, long long val, int tm) {
  19.         typ = t;
  20.         value = val;
  21.         time = tm;
  22.     }
  23. };
  24.  
  25. bool cmp(lazy a, lazy b) {
  26.     if (a.time < b.time) return true;
  27.     return false;
  28. }
  29.  
  30. struct vert {
  31.     long long sum;
  32.     long long child;
  33.     vector<lazy> updates;
  34.     vert() {
  35.         sum = child = 0;
  36.         updates.clear();
  37.     }
  38. };
  39.  
  40. int N;
  41. int A[Size];
  42. int last_node = 1;
  43. vert tree[Size * 4];
  44.  
  45. inline void update_Mod(int cur) {
  46.     if (tree[cur].sum >= Mod){
  47.         tree[cur].sum %= Mod;
  48.     }
  49. }
  50.  
  51. void build_tree(int cur, int Start, int End) {
  52.     last_node = max(last_node, cur);
  53.     if (Start == End) {
  54.         tree[cur].sum = A[Start];
  55.         tree[cur].child = 1;
  56.         return;
  57.     }
  58.     int left = cur * 2;
  59.     int right = cur * 2 + 1;
  60.     int mid = (Start + End) / 2;
  61.     build_tree(left, Start, mid);
  62.     build_tree(right, mid + 1, End);
  63.     tree[cur].sum = tree[left].sum + tree[right].sum;
  64.     tree[cur].child = tree[left].child + tree[right].child;
  65.     update_Mod(cur);
  66. }
  67.  
  68. inline void update_child(int cur, int left, int right) {
  69.     if (tree[cur].updates.empty() == true){
  70.         return;
  71.     }
  72.     sort(tree[cur].updates.begin(), tree[cur].updates.end(), cmp);
  73.     int Len = tree[cur].updates.size();
  74.     int last_reset_pos = 0;
  75.     for (int i = 0; i < Len; i++) {
  76.         if (tree[cur].updates[i].typ == 3) {
  77.             last_reset_pos = i;
  78.         }
  79.     }
  80.     if (last_reset_pos != 0){
  81.         tree[cur].updates.erase(tree[cur].updates.begin(), tree[cur].updates.begin() + last_reset_pos);
  82.     }
  83.     Len = tree[cur].updates.size();
  84.     long long res = 0, sum = 0,mty = 1;
  85.     for (int i = 0; i < Len; i++) {
  86.         if (tree[cur].updates[i].typ == 1) {
  87.             sum += tree[cur].updates[i].value;
  88.         } else if(tree[cur].updates[i].typ == 3){
  89.             res = tree[cur].updates[i].value;
  90.         }else{
  91.             mty = (tree[cur].updates[i].value * mty);
  92.             if(mty >= Mod) mty %= Mod;
  93.         }
  94.         tree[left].updates.push_back(tree[cur].updates[i]);
  95.         tree[right].updates.push_back(tree[cur].updates[i]);
  96.     }
  97.     if (res != 0) {
  98.         tree[left].sum = res * tree[left].child;
  99.         tree[right].sum = res * tree[right].child;
  100.     }
  101.     if(sum != 0){
  102.         tree[left].sum += (sum * tree[left].child);
  103.         tree[right].sum += (sum * tree[right].child);
  104.     }
  105.     if(mty != 1){
  106.         tree[left].sum = (tree[left].sum * mty);
  107.         if(tree[left].sum >= Mod) tree[left].sum %= Mod;
  108.         tree[right].sum = (tree[right].sum * mty);
  109.         if(tree[right].sum >= Mod) tree[right].sum %= Mod;
  110.     }
  111.     //printf("Update in left: %d = %d & right: %d = %d\n",left,tree[left].sum,right,tree[right].sum);
  112.     tree[cur].updates.clear();
  113. }
  114.  
  115. void update_tree_add(int cur, int Start, int End, int i, int j, long long val, int time) {
  116.     if (End < i || Start > j) {
  117.         return;
  118.     }
  119.     int left = cur * 2;
  120.     int right = cur * 2 + 1;
  121.     int mid = (Start + End) / 2;
  122.  
  123.     if (Start >= i && End <= j) {
  124.         update_child(cur, left, right);
  125.  
  126.         tree[cur].updates.push_back(lazy(1, val, time));
  127.         tree[cur].sum += (tree[cur].child * val);
  128.         update_Mod(cur);
  129.         return;
  130.     }
  131.     update_child(cur, left, right);
  132.  
  133.     update_tree_add(left, Start, mid, i, j, val, time);
  134.     update_tree_add(right, mid + 1, End, i, j, val, time);
  135.     tree[cur].sum = tree[left].sum + tree[right].sum;
  136.     update_Mod(cur);
  137. }
  138.  
  139. void update_tree_multi(int cur, int Start, int End, int i, int j, long long val, int time) {
  140.     if (End < i || Start > j) {
  141.         return;
  142.     }
  143.     int left = cur * 2;
  144.     int right = cur * 2 + 1;
  145.     int mid = (Start + End) / 2;
  146.  
  147.     if (Start >= i && End <= j) {
  148.         update_child(cur, left, right);
  149.  
  150.         tree[cur].updates.push_back(lazy(2, val, time));
  151.         tree[cur].sum = (tree[cur].sum * val);
  152.         if(tree[cur].sum >= Mod) tree[cur].sum %= Mod;
  153.         //printf("Saved in %d = %d\n",cur,tree[cur].sum);
  154.         return;
  155.     }
  156.     update_child(cur, left, right);
  157.  
  158.     update_tree_multi(left, Start, mid, i, j, val, time);
  159.     update_tree_multi(right, mid + 1, End, i, j, val, time);
  160.     tree[cur].sum = tree[left].sum + tree[right].sum;
  161.     //printf("Merge in cur: %d = %d\n",cur,tree[cur].sum);
  162.     update_Mod(cur);
  163. }
  164.  
  165. void update_tree_reset(int cur, int Start, int End, int i, int j, long long val, int time) {
  166.     if (End < i || Start > j) {
  167.         return;
  168.     }
  169.     int left = cur * 2;
  170.     int right = cur * 2 + 1;
  171.     int mid = (Start + End) / 2;
  172.  
  173.     if (Start >= i && End <= j) {
  174.         update_child(cur, left, right);
  175.         tree[cur].sum = tree[cur].child * val;
  176.         tree[cur].updates.push_back(lazy(3, val, time));
  177.         update_Mod(cur);
  178.         return;
  179.     }
  180.     update_child(cur, left, right);
  181.  
  182.     update_tree_reset(left, Start, mid, i, j, val, time);
  183.     update_tree_reset(right, mid + 1, End, i, j, val, time);
  184.     tree[cur].sum = tree[left].sum + tree[right].sum;
  185.     update_Mod(cur);
  186. }
  187.  
  188. long long query_tree(int cur, int Start, int End, int i, int j) {
  189.     if (End < i || Start > j) {
  190.         return 0;
  191.     }
  192.     if (Start >= i && End <= j) {
  193.         return tree[cur].sum;
  194.     }
  195.     int left = cur * 2;
  196.     int right = cur * 2 + 1;
  197.     int mid = (Start + End) / 2;
  198.  
  199.     update_child(cur, left, right);
  200.  
  201.     long long s1 = query_tree(left, Start, mid, i, j);
  202.     long long s2 = query_tree(right, mid + 1, End, i, j);
  203.     update_Mod(cur);
  204.     return (s1 + s2) % Mod;
  205. }
  206.  
  207. int main() {
  208.     int Q, typ, u, v, val;
  209.     scanf("%d %d", &N, &Q);
  210.     for (int i = 1; i <= N; i++) {
  211.         scanf("%d", &A[i]);
  212.     }
  213.     build_tree(1, 1, N);
  214.     //print_tree();
  215.     for (int i = 0; i < Q; i++) {
  216.         scanf("%d", &typ);
  217.         if (typ == 1) {
  218.             scanf("%d %d %d", &u, &v, &val);
  219.             update_tree_add(1, 1, N, u, v, val, i);
  220.         } else if (typ == 2) {
  221.             scanf("%d %d %d", &u, &v, &val);
  222.             update_tree_multi(1, 1, N, u, v, val, i);
  223.         } else if (typ == 3) {
  224.             scanf("%d %d %d", &u, &v, &val);
  225.             update_tree_reset(1, 1, N, u, v, val, i);
  226.         } else {
  227.             scanf("%d %d", &u, &v);
  228.             long long res = query_tree(1, 1, N, u, v);
  229.             printf("%lld\n", res);
  230.         }
  231.         //print_tree();
  232.     }
  233.     return 0;
  234. }
Advertisement
Add Comment
Please, Sign In to add comment