Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //============================================================================
- // Name : ACM
- // Author : Tarango Khan
- // Copyright : Team Byteheads
- // Description : !!!Hello World!!!
- //============================================================================
- #include <bits/stdc++.h>
- using namespace std;
- #define inf 99999999
- #define Size 1000050
- #define Mod 1000000007
- struct lazy {
- int typ;
- long long value;
- int time;
- lazy(int t, long long val, int tm) {
- typ = t;
- value = val;
- time = tm;
- }
- };
- bool cmp(lazy a, lazy b) {
- if (a.time < b.time) return true;
- return false;
- }
- struct vert {
- long long sum;
- long long child;
- vector<lazy> updates;
- vert() {
- sum = child = 0;
- updates.clear();
- }
- };
- int N;
- int A[Size];
- int last_node = 1;
- vert tree[Size * 4];
- inline void update_Mod(int cur) {
- if (tree[cur].sum >= Mod){
- tree[cur].sum %= Mod;
- }
- }
- void build_tree(int cur, int Start, int End) {
- last_node = max(last_node, cur);
- if (Start == End) {
- tree[cur].sum = A[Start];
- tree[cur].child = 1;
- return;
- }
- int left = cur * 2;
- int right = cur * 2 + 1;
- int mid = (Start + End) / 2;
- build_tree(left, Start, mid);
- build_tree(right, mid + 1, End);
- tree[cur].sum = tree[left].sum + tree[right].sum;
- tree[cur].child = tree[left].child + tree[right].child;
- update_Mod(cur);
- }
- inline void update_child(int cur, int left, int right) {
- if (tree[cur].updates.empty() == true){
- return;
- }
- sort(tree[cur].updates.begin(), tree[cur].updates.end(), cmp);
- int Len = tree[cur].updates.size();
- int last_reset_pos = 0;
- for (int i = 0; i < Len; i++) {
- if (tree[cur].updates[i].typ == 3) {
- last_reset_pos = i;
- }
- }
- if (last_reset_pos != 0){
- tree[cur].updates.erase(tree[cur].updates.begin(), tree[cur].updates.begin() + last_reset_pos);
- }
- Len = tree[cur].updates.size();
- long long res = 0, sum = 0,mty = 1;
- for (int i = 0; i < Len; i++) {
- if (tree[cur].updates[i].typ == 1) {
- sum += tree[cur].updates[i].value;
- } else if(tree[cur].updates[i].typ == 3){
- res = tree[cur].updates[i].value;
- }else{
- mty = (tree[cur].updates[i].value * mty);
- if(mty >= Mod) mty %= Mod;
- }
- tree[left].updates.push_back(tree[cur].updates[i]);
- tree[right].updates.push_back(tree[cur].updates[i]);
- }
- if (res != 0) {
- tree[left].sum = res * tree[left].child;
- tree[right].sum = res * tree[right].child;
- }
- if(sum != 0){
- tree[left].sum += (sum * tree[left].child);
- tree[right].sum += (sum * tree[right].child);
- }
- if(mty != 1){
- tree[left].sum = (tree[left].sum * mty);
- if(tree[left].sum >= Mod) tree[left].sum %= Mod;
- tree[right].sum = (tree[right].sum * mty);
- if(tree[right].sum >= Mod) tree[right].sum %= Mod;
- }
- //printf("Update in left: %d = %d & right: %d = %d\n",left,tree[left].sum,right,tree[right].sum);
- tree[cur].updates.clear();
- }
- void update_tree_add(int cur, int Start, int End, int i, int j, long long val, int time) {
- if (End < i || Start > j) {
- return;
- }
- int left = cur * 2;
- int right = cur * 2 + 1;
- int mid = (Start + End) / 2;
- if (Start >= i && End <= j) {
- update_child(cur, left, right);
- tree[cur].updates.push_back(lazy(1, val, time));
- tree[cur].sum += (tree[cur].child * val);
- update_Mod(cur);
- return;
- }
- update_child(cur, left, right);
- update_tree_add(left, Start, mid, i, j, val, time);
- update_tree_add(right, mid + 1, End, i, j, val, time);
- tree[cur].sum = tree[left].sum + tree[right].sum;
- update_Mod(cur);
- }
- void update_tree_multi(int cur, int Start, int End, int i, int j, long long val, int time) {
- if (End < i || Start > j) {
- return;
- }
- int left = cur * 2;
- int right = cur * 2 + 1;
- int mid = (Start + End) / 2;
- if (Start >= i && End <= j) {
- update_child(cur, left, right);
- tree[cur].updates.push_back(lazy(2, val, time));
- tree[cur].sum = (tree[cur].sum * val);
- if(tree[cur].sum >= Mod) tree[cur].sum %= Mod;
- //printf("Saved in %d = %d\n",cur,tree[cur].sum);
- return;
- }
- update_child(cur, left, right);
- update_tree_multi(left, Start, mid, i, j, val, time);
- update_tree_multi(right, mid + 1, End, i, j, val, time);
- tree[cur].sum = tree[left].sum + tree[right].sum;
- //printf("Merge in cur: %d = %d\n",cur,tree[cur].sum);
- update_Mod(cur);
- }
- void update_tree_reset(int cur, int Start, int End, int i, int j, long long val, int time) {
- if (End < i || Start > j) {
- return;
- }
- int left = cur * 2;
- int right = cur * 2 + 1;
- int mid = (Start + End) / 2;
- if (Start >= i && End <= j) {
- update_child(cur, left, right);
- tree[cur].sum = tree[cur].child * val;
- tree[cur].updates.push_back(lazy(3, val, time));
- update_Mod(cur);
- return;
- }
- update_child(cur, left, right);
- update_tree_reset(left, Start, mid, i, j, val, time);
- update_tree_reset(right, mid + 1, End, i, j, val, time);
- tree[cur].sum = tree[left].sum + tree[right].sum;
- update_Mod(cur);
- }
- long long query_tree(int cur, int Start, int End, int i, int j) {
- if (End < i || Start > j) {
- return 0;
- }
- if (Start >= i && End <= j) {
- return tree[cur].sum;
- }
- int left = cur * 2;
- int right = cur * 2 + 1;
- int mid = (Start + End) / 2;
- update_child(cur, left, right);
- long long s1 = query_tree(left, Start, mid, i, j);
- long long s2 = query_tree(right, mid + 1, End, i, j);
- update_Mod(cur);
- return (s1 + s2) % Mod;
- }
- int main() {
- int Q, typ, u, v, val;
- scanf("%d %d", &N, &Q);
- for (int i = 1; i <= N; i++) {
- scanf("%d", &A[i]);
- }
- build_tree(1, 1, N);
- //print_tree();
- for (int i = 0; i < Q; i++) {
- scanf("%d", &typ);
- if (typ == 1) {
- scanf("%d %d %d", &u, &v, &val);
- update_tree_add(1, 1, N, u, v, val, i);
- } else if (typ == 2) {
- scanf("%d %d %d", &u, &v, &val);
- update_tree_multi(1, 1, N, u, v, val, i);
- } else if (typ == 3) {
- scanf("%d %d %d", &u, &v, &val);
- update_tree_reset(1, 1, N, u, v, val, i);
- } else {
- scanf("%d %d", &u, &v);
- long long res = query_tree(1, 1, N, u, v);
- printf("%lld\n", res);
- }
- //print_tree();
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment