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 vert{
- long long sum;
- long long add;
- long long mpy;
- long long reset;
- long long child;
- vert(){
- sum = add = mpy = reset = child = 0;
- mpy = 1;
- }
- };
- int N;
- int A[Size];
- vert tree[Size * 4];
- inline void update_Mod(int cur) {
- if (tree[cur].sum >= Mod){
- tree[cur].sum %= Mod;
- }
- if (tree[cur].mpy >= Mod){
- tree[cur].mpy %= Mod;
- }
- if (tree[cur].add >= Mod){
- tree[cur].add %= Mod;
- }
- if (tree[cur].reset >= Mod){
- tree[cur].reset %= Mod;
- }
- }
- void build_tree(int cur, int Start, int End) {
- 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);
- }
- void update_child(int cur,int left,int right){
- if(tree[cur].reset != 0){
- tree[left].add = 0;
- tree[left].mpy = 1;
- tree[left].reset = tree[cur].reset;
- tree[left].sum = tree[left].child * tree[left].reset;
- tree[right].add = 0;
- tree[right].mpy = 1;
- tree[right].reset = tree[cur].reset;
- tree[right].sum = tree[right].child * tree[right].reset;
- tree[cur].reset = 0;
- }
- if(tree[cur].add != 0){
- tree[left].add += tree[cur].add;
- tree[left].sum += (tree[left].child * tree[cur].add);
- tree[right].add += tree[cur].add;
- tree[right].sum += (tree[right].child * tree[cur].add);
- tree[cur].add = 0;
- }
- if(tree[cur].mpy != 1){
- tree[left].mpy *= tree[cur].mpy;
- tree[left].sum *= tree[cur].mpy;
- tree[right].mpy *= tree[cur].mpy;
- tree[right].sum *= tree[cur].mpy;
- tree[cur].mpy = 1;
- update_Mod(cur);
- update_Mod(left);
- update_Mod(right);
- }
- }
- void update_tree_add(int cur, int Start, int End, int i, int j, long long val) {
- 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].add += val;
- 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);
- update_tree_add(right, mid + 1, End, i, j, val);
- 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) {
- 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].mpy *= val;
- tree[cur].sum = (tree[cur].sum * val);
- update_Mod(cur);
- update_Mod(left);
- update_Mod(right);
- return;
- }
- update_child(cur, left, right);
- update_tree_multi(left, Start, mid, i, j, val);
- update_tree_multi(right, mid + 1, End, i, j, val);
- tree[cur].sum = tree[left].sum + tree[right].sum;
- update_Mod(cur);
- update_Mod(left);
- update_Mod(right);
- }
- void update_tree_reset(int cur, int Start, int End, int i, int j, long long val) {
- 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) {
- tree[cur].reset = val;
- tree[cur].sum = tree[cur].child * val;
- tree[cur].add = 0;
- tree[cur].mpy = 1;
- update_Mod(cur);
- update_Mod(left);
- update_Mod(right);
- return;
- }
- update_child(cur, left, right);
- update_tree_reset(left, Start, mid, i, j, val);
- update_tree_reset(right, mid + 1, End, i, j, val);
- tree[cur].sum = tree[left].sum + tree[right].sum;
- update_Mod(cur);
- update_Mod(left);
- update_Mod(right);
- }
- 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);
- update_Mod(left);
- update_Mod(right);
- 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);
- 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);
- } else if (typ == 2) {
- scanf("%d %d %d", &u, &v, &val);
- update_tree_multi(1, 1, N, u, v, val);
- } else if (typ == 3) {
- scanf("%d %d %d", &u, &v, &val);
- update_tree_reset(1, 1, N, u, v, val);
- } else {
- scanf("%d %d", &u, &v);
- long long res = query_tree(1, 1, N, u, v);
- printf("%lld\n", res);
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment