luogu2023 [AHOI2009]维护序列

时间:2023-03-09 01:51:07
luogu2023 [AHOI2009]维护序列

线段树加乘懒标记裸题。

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
int n, mod, m, t, u, v;
ll w;
struct SGT{
ll sum[400005];
ll lzt[400005];
ll mul[400005];
void built(int o, int l, int r){
lzt[o] = 0;
mul[o] = 1;
if(l==r) scanf("%lld", &sum[o]);
else{
int mid=(l+r)>>1;
int lson=o<<1;
int rson=lson|1;
if(l<=mid) built(lson, l, mid);
if(mid<r) built(rson, mid+1, r);
sum[o] = (sum[lson] + sum[rson]) % mod;
}
}
void push_down(int o, int l, int r, int lson, int rson, int mid){
mul[lson] = (mul[o] * mul[lson]) % mod;
mul[rson] = (mul[o] * mul[rson]) % mod;
lzt[lson] = (mul[o] * lzt[lson]) % mod;
lzt[rson] = (mul[o] * lzt[rson]) % mod;
sum[lson] = (mul[o] * sum[lson]) % mod;
sum[rson] = (mul[o] * sum[rson]) % mod;
mul[o] = 1;
lzt[lson] = (lzt[o] + lzt[lson]) % mod;
lzt[rson] = (lzt[o] + lzt[rson]) % mod;
sum[lson] = (sum[lson] + (mid-l+1) * lzt[o]) % mod;
sum[rson] = (sum[rson] + (r-mid) * lzt[o]) % mod;
lzt[o] = 0;
}
void update_add(int o, int l, int r, int x, int y, ll k){
if(l>=x && r<=y){
sum[o] = (sum[o] + (r-l+1) * k) % mod;
lzt[o] = (lzt[o] + k) % mod;
}
else{
int mid=(l+r)>>1;
int lson=o<<1;
int rson=lson|1;
if(mul[o]!=1 || lzt[o]) push_down(o, l, r, lson, rson, mid);
if(x<=mid) update_add(lson, l, mid, x, y, k);
if(mid<y) update_add(rson, mid+1, r, x, y, k);
sum[o] = (sum[lson] + sum[rson]) % mod;
}
}
void update_mul(int o, int l, int r, int x, int y, ll k){
if(l>=x && r<=y){
mul[o] = (mul[o] * k) % mod;
lzt[o] = (lzt[o] * k) % mod;
sum[o] = (sum[o] * k) % mod;
}
else{
int mid=(l+r)>>1;
int lson=o<<1;
int rson=lson|1;
if(mul[o]!=1 || lzt[o]) push_down(o, l, r, lson, rson, mid);
if(x<=mid) update_mul(lson, l, mid, x, y, k);
if(mid<y) update_mul(rson, mid+1, r, x, y, k);
sum[o] = (sum[lson] + sum[rson]) % mod;
}
}
ll query(int o, int l, int r, int x, int y){
if(l>=x && r<=y) return sum[o];
else{
int mid=(l+r)>>1;
int lson=o<<1;
int rson=lson|1;
ll ans=0;
if(mul[o]!=1 || lzt[o]) push_down(o, l, r, lson, rson, mid);
if(x<=mid) ans = (ans + query(lson, l, mid, x, y)) % mod;
if(mid<y) ans = (ans + query(rson, mid+1, r, x, y)) % mod;
return ans;
}
}
}sgt;
int main(){
cin>>n>>mod;
sgt.built(1, 1, n);
cin>>m;
while(m--){
scanf("%d", &t);
if(t==1){
scanf("%d %d %lld", &u, &v, &w);
sgt.update_mul(1, 1, n, u, v, w);
}
else if(t==2){
scanf("%d %d %lld", &u, &v, &w);
sgt.update_add(1, 1, n, u, v, w);
}
else{
scanf("%d %d", &u, &v);
printf("%lld\n", sgt.query(1, 1, n, u, v));
}
}
return 0;
}