Tarango

ADD MULTIPLICATION Updated

Jul 9th, 2015
342
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.20 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 vert{
  15.     long long sum;
  16.     long long add;
  17.     long long mpy;
  18.     long long reset;
  19.     long long child;
  20.     vert(){
  21.         sum = add = mpy = reset = child = 0;
  22.         mpy = 1;
  23.     }
  24. };
  25.  
  26. int N;
  27. int A[Size];
  28. vert tree[Size * 4];
  29.  
  30. inline void update_Mod(int cur) {
  31.     if (tree[cur].sum >= Mod){
  32.         tree[cur].sum %= Mod;
  33.     }
  34.     if (tree[cur].mpy >= Mod){
  35.         tree[cur].mpy %= Mod;
  36.     }
  37.     if (tree[cur].add >= Mod){
  38.         tree[cur].add %= Mod;
  39.     }
  40.     if (tree[cur].reset >= Mod){
  41.         tree[cur].reset %= Mod;
  42.     }
  43. }
  44.  
  45. void build_tree(int cur, int Start, int End) {
  46.     if (Start == End) {
  47.         tree[cur].sum = A[Start];
  48.         tree[cur].child = 1;
  49.         return;
  50.     }
  51.     int left = cur * 2;
  52.     int right = cur * 2 + 1;
  53.     int mid = (Start + End) / 2;
  54.     build_tree(left, Start, mid);
  55.     build_tree(right, mid + 1, End);
  56.     tree[cur].sum = tree[left].sum + tree[right].sum;
  57.     tree[cur].child = tree[left].child + tree[right].child;
  58.     update_Mod(cur);
  59. }
  60.  
  61. void update_child(int cur,int left,int right){
  62.     if(tree[cur].reset != 0){
  63.         tree[left].add = 0;
  64.         tree[left].mpy = 1;
  65.         tree[left].reset = tree[cur].reset;
  66.         tree[left].sum = tree[left].child * tree[left].reset;
  67.         tree[right].add = 0;
  68.         tree[right].mpy = 1;
  69.         tree[right].reset = tree[cur].reset;
  70.         tree[right].sum = tree[right].child * tree[right].reset;
  71.         tree[cur].reset = 0;
  72.     }
  73.     if(tree[cur].add != 0){
  74.         tree[left].add += tree[cur].add;
  75.         tree[left].sum += (tree[left].child * tree[cur].add);
  76.         tree[right].add += tree[cur].add;
  77.         tree[right].sum += (tree[right].child * tree[cur].add);
  78.         tree[cur].add = 0;
  79.     }
  80.     if(tree[cur].mpy != 1){
  81.         tree[left].mpy *= tree[cur].mpy;
  82.         tree[left].sum *= tree[cur].mpy;
  83.         tree[right].mpy *= tree[cur].mpy;
  84.         tree[right].sum *= tree[cur].mpy;
  85.         tree[cur].mpy = 1;
  86.         update_Mod(cur);
  87.         update_Mod(left);
  88.         update_Mod(right);
  89.     }
  90. }
  91.  
  92. void update_tree_add(int cur, int Start, int End, int i, int j, long long val) {
  93.     if (End < i || Start > j) {
  94.         return;
  95.     }
  96.     int left = cur * 2;
  97.     int right = cur * 2 + 1;
  98.     int mid = (Start + End) / 2;
  99.  
  100.     if (Start >= i && End <= j) {
  101.         update_child(cur, left, right);
  102.         tree[cur].add += val;
  103.         tree[cur].sum += (tree[cur].child * val);
  104.         update_Mod(cur);
  105.         return;
  106.     }
  107.     update_child(cur, left, right);
  108.  
  109.     update_tree_add(left, Start, mid, i, j, val);
  110.     update_tree_add(right, mid + 1, End, i, j, val);
  111.     tree[cur].sum = tree[left].sum + tree[right].sum;
  112.     update_Mod(cur);
  113. }
  114.  
  115. void update_tree_multi(int cur, int Start, int End, int i, int j, long long val) {
  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.         tree[cur].mpy *= val;
  126.         tree[cur].sum = (tree[cur].sum * val);
  127.         update_Mod(cur);
  128.         update_Mod(left);
  129.         update_Mod(right);
  130.         return;
  131.     }
  132.     update_child(cur, left, right);
  133.  
  134.     update_tree_multi(left, Start, mid, i, j, val);
  135.     update_tree_multi(right, mid + 1, End, i, j, val);
  136.     tree[cur].sum = tree[left].sum + tree[right].sum;
  137.     update_Mod(cur);
  138.     update_Mod(left);
  139.     update_Mod(right);
  140. }
  141.  
  142. void update_tree_reset(int cur, int Start, int End, int i, int j, long long val) {
  143.     if (End < i || Start > j) {
  144.         return;
  145.     }
  146.     int left = cur * 2;
  147.     int right = cur * 2 + 1;
  148.     int mid = (Start + End) / 2;
  149.  
  150.     if (Start >= i && End <= j) {
  151.         tree[cur].reset = val;
  152.         tree[cur].sum = tree[cur].child * val;
  153.         tree[cur].add = 0;
  154.         tree[cur].mpy = 1;
  155.         update_Mod(cur);
  156.         update_Mod(left);
  157.         update_Mod(right);
  158.         return;
  159.     }
  160.     update_child(cur, left, right);
  161.  
  162.     update_tree_reset(left, Start, mid, i, j, val);
  163.     update_tree_reset(right, mid + 1, End, i, j, val);
  164.     tree[cur].sum = tree[left].sum + tree[right].sum;
  165.     update_Mod(cur);
  166.     update_Mod(left);
  167.     update_Mod(right);
  168. }
  169.  
  170. long long query_tree(int cur, int Start, int End, int i, int j) {
  171.     if (End < i || Start > j) {
  172.         return 0;
  173.     }
  174.     if (Start >= i && End <= j) {
  175.         return tree[cur].sum;
  176.     }
  177.     int left = cur * 2;
  178.     int right = cur * 2 + 1;
  179.     int mid = (Start + End) / 2;
  180.  
  181.     update_child(cur, left, right);
  182.  
  183.     long long s1 = query_tree(left, Start, mid, i, j);
  184.     long long s2 = query_tree(right, mid + 1, End, i, j);
  185.     update_Mod(cur);
  186.     update_Mod(left);
  187.     update_Mod(right);
  188.     return (s1 + s2) % Mod;
  189. }
  190.  
  191. int main() {
  192.     int Q, typ, u, v, val;
  193.     scanf("%d %d", &N, &Q);
  194.     for (int i = 1; i <= N; i++) {
  195.         scanf("%d", &A[i]);
  196.     }
  197.     build_tree(1, 1, N);
  198.     for (int i = 0; i < Q; i++) {
  199.         scanf("%d", &typ);
  200.         if (typ == 1) {
  201.             scanf("%d %d %d", &u, &v, &val);
  202.             update_tree_add(1, 1, N, u, v, val);
  203.         } else if (typ == 2) {
  204.             scanf("%d %d %d", &u, &v, &val);
  205.             update_tree_multi(1, 1, N, u, v, val);
  206.         } else if (typ == 3) {
  207.             scanf("%d %d %d", &u, &v, &val);
  208.             update_tree_reset(1, 1, N, u, v, val);
  209.         } else {
  210.             scanf("%d %d", &u, &v);
  211.             long long res = query_tree(1, 1, N, u, v);
  212.             printf("%lld\n", res);
  213.         }
  214.     }
  215.     return 0;
  216. }
Advertisement
Add Comment
Please, Sign In to add comment