bzoj1798 [Ahoi2009]Seq 维护序列seq 线段树
此题甚坑,一开始我一直怀疑线段树敲渣了,最后发现又没开longlong QAQ
我居然蠢蠢地连改了几个无关紧要的东西疯狂地交
过了以后看到网上大神的左右儿子都用define写,表示羡慕,开始改程序(MDZZ还RE了一遍),希望以后再写线段树的时候能记得用define缩代码减少点错误
主要是标记的变化(增加或下移)时乘法一定要转移全(标记和树上维护的和都要更新)
其他就是简单的裸线段树(其实整个就是裸的,只是智障症犯了)
1 #include <cstdio> 2 #define lson l,mid,now<<1 3 #define rson mid+1,r,now<<1|1 4 #define N 100010 5 using namespace std; 6 typedef long long ll; 7 ll mul[N<<2],sum[N<<2],add[N<<2]; 8 int n,mod,q,opt,x,y; 9 void pushup(int now) 10 { 11 sum[now]=(sum[now<<1]+sum[now<<1|1])%mod; 12 } 13 void pushdown(int now,ll m) 14 { 15 if(mul[now]!=1||add[now]!=0) 16 { 17 mul[now<<1]=(mul[now<<1]*mul[now])%mod; 18 mul[now<<1|1]=(mul[now<<1|1]*mul[now])%mod; 19 add[now<<1]=(mul[now]*add[now<<1]+add[now])%mod; 20 add[now<<1|1]=(mul[now]*add[now<<1|1]+add[now])%mod; 21 sum[now<<1]=(sum[now<<1]*mul[now]+(m-(m>>1))*add[now])%mod; 22 sum[now<<1|1]=(sum[now<<1|1]*mul[now]+(m>>1)*add[now])%mod; 23 mul[now]=1,add[now]=0; 24 } 25 } 26 void build(int l,int r,int now) 27 { 28 mul[now]=1,sum[now]=0; 29 if(l==r) 30 { 31 scanf("%I64d",&sum[now]); 32 return; 33 } 34 int mid=(l+r)>>1; 35 build(lson),build(rson); 36 pushup(now); 37 } 38 void _mul(int L,int R,int l,int r,int now,ll c) 39 { 40 if(L<=l&&r<=R) 41 { 42 mul[now]=(mul[now]*c)%mod; 43 add[now]=(add[now]*c)%mod; 44 sum[now]=(sum[now]*c)%mod; 45 return; 46 } 47 pushdown(now,r-l+1); 48 int mid=(l+r)>>1; 49 if(L<=mid)_mul(L,R,lson,c); 50 if(R>mid) _mul(L,R,rson,c); 51 pushup(now); 52 } 53 void _add(int L,int R,int l,int r,int now,ll c) 54 { 55 if(L<=l&&r<=R) 56 { 57 add[now]=(add[now]+c)%mod; 58 sum[now]=(sum[now]+(r-l+1)*c)%mod; 59 return; 60 } 61 pushdown(now,r-l+1); 62 int mid=(l+r)>>1; 63 if(L<=mid) 64 _add(L,R,lson,c); 65 if(R>mid) 66 _add(L,R,rson,c); 67 pushup(now); 68 } 69 ll query(int L,int R,int l,int r,int now) 70 { 71 if(L<=l&&r<=R) 72 { 73 return sum[now]; 74 } 75 pushdown(now,r-l+1); 76 int mid=(l+r)>>1; 77 ll ans=0; 78 if(L<=mid) 79 ans=(ans+query(L,R,lson))%mod; 80 if(R>mid) 81 ans=(ans+query(L,R,rson))%mod; 82 pushup(now); 83 return ans; 84 } 85 int main() 86 { 87 scanf("%d%d",&n,&mod); 88 build(1,n,1); 89 scanf("%d",&q); 90 while(q--) 91 { 92 scanf("%d",&opt); 93 scanf("%d%d",&x,&y); 94 int z; 95 switch(opt) 96 { 97 case 1:scanf("%d",&z);_mul(x,y,1,n,1,z);break; 98 case 2:scanf("%d",&z);_add(x,y,1,n,1,z);break; 99 case 3:printf("%lld\n",query(x,y,1,n,1));break; 100 } 101 } 102 }