voidpushdown(int x , int l , int r){ if(!node[x].add_tag){ return ; } int mid = (l + r) >> 1; node[lson(x)].add_tag += node[x].add_tag; node[rson(x)].add_tag += node[x].add_tag; node[lson(x)].num += node[x].add_tag * (mid - l + 1); node[rson(x)].num += node[x].add_tag * (r - mid); node[x].add_tag = 0; } voidbuild(int x , int l , int r){ if(l == r){ node[x].num = a[r]; return ; } int mid = (l + r) >> 1; build(lson(x) , l , mid); build(rson(x) , mid + 1 , r); pushup(x); } voidrange_add(int x , int l , int r , int ql , int qr , ll v){ if(ql <= l && r <= qr){ node[x].add_tag += v; node[x].num += v * (r - l + 1); return ; } pushdown(x , l , r); int mid = (l + r) >> 1; if(ql <= mid){ range_add(lson(x) , l , mid , ql , qr , v); } if(qr >= mid + 1){ range_add(rson(x) , mid + 1 , r , ql , qr , v); } pushup(x); } ll range_query(int x , int l , int r , int ql , int qr){ if(ql <= l && r <= qr){ return node[x].num; } pushdown(x , l , r); int mid = (l + r) >> 1; ll ans = 0; if(ql <= mid){ ans += range_query(lson(x) , l , mid , ql , qr); } if(qr >= mid + 1){ ans += range_query(rson(x) , mid + 1 , r , ql , qr); } return ans; } }
usingnamespace Segtree;
intmain(){ int opt; ll x , y , k; cin >> n >> m; for(int i = 1; i <= n; i ++){ cin >> a[i]; } build(1 , 1 , n); for(int i = 1; i <= m; i ++){ cin >> opt; if(opt == 1){ cin >> x >> y >> k; range_add(1 , 1 , n , x , y , k); } elseif(opt == 2){ cin >> x >> y; cout << range_query(1 , 1 , n , x , y) << endl; } } return0; }
voidbuild(int x , int l , int r){ node[x].mul_tag = 1; if(l == r){ node[x].num = a[r]; return ; } int mid = (l + r) >> 1; build(lson(x) , l , mid); build(rson(x) , mid + 1 , r); pushup(x); }
voidrange_add(int x , int l , int r , int ql , int qr , ll v){ if(ql <= l && r <= qr){ node[x].add_tag += v; node[x].add_tag %= p; node[x].num += v * (r - l + 1); node[x].num %= p; return; } pushdown(x , l , r); int mid = (l + r) >> 1; if(ql <= mid){ range_add(lson(x) , l , mid , ql , qr , v); } if(qr >= mid + 1){ range_add(rson(x) , mid + 1 , r , ql , qr , v); } pushup(x); }
voidrange_mul(int x , int l , int r , int ql , int qr , ll v){ if(ql <= l && r <= qr){ node[x].mul_tag *= v; node[x].mul_tag %= p; node[x].add_tag *= v; node[x].add_tag %= p; node[x].num *= v; node[x].num %= p; return ; } pushdown(x , l , r); int mid = (l + r) >> 1; if(ql <= mid){ range_mul(lson(x) , l , mid , ql , qr , v); } if(qr >= mid + 1){ range_mul(rson(x) , mid + 1 , r , ql , qr , v); } pushup(x); } ll range_query(int x , int l , int r , int ql , int qr){ if(ql <= l && qr >= r){ return node[x].num % p; } pushdown(x , l , r); int mid = (l + r) >> 1; ll ans = 0; if(ql <= mid){ ans += range_query(lson(x) , l , mid , ql , qr); ans %= p; } if(qr >= mid + 1){ ans += range_query(rson(x) , mid + 1 , r , ql , qr); ans %= p; } return ans % p; } }
usingnamespace Segtree;
intmain(){ int opt; ll x , y , k; cin >> n >> m >> p; for(int i = 1; i <= n; i ++){ cin >> a[i]; } build(1 , 1 , n); for(int i = 1; i <= m; i ++){ cin >> opt; if(opt == 1){ cin >> x >> y >> k; range_mul(1 , 1 , n , x , y , k % p); } elseif(opt == 2){ cin >> x >> y >> k; range_add(1 , 1 , n , x , y , k % p); } elseif(opt == 3){ cin >> x >> y; cout << range_query(1 , 1 , n , x , y) << endl; } } return0; }