双倍的快乐 P2023 [AHOI2009]维护序列 P3373 【模板】线段树 2
看学长的模板然后改了一下
要注意每次询问时pushdown 然后就是这道题要注意开longlong 从学长那里学来的*1ll好像对我并没有什么用QAQ
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<queue> 6 #include<cmath> 7 #include<vector> 8 #include<stack> 9 #include<map> 10 #include<set> 11 #define Run(i,l,r) for(int i=l;i<=r;i++) 12 #define Don(i,l,r) for(int i=l;i>=r;i--) 13 #define ll long long 14 #define ld long double 15 #define inf 0x3f3f3f3f 16 #define ls k<<1 17 #define rs (k<<1|1) 18 #define rg register 19 using namespace std; 20 const int N=100010; 21 int n,m,sum[N<<2],lz1[N<<2],lz2[N<<2],mod; 22 char gc(){ 23 static char*p1,*p2,s[1000000]; 24 if(p1==p2)p2=(p1=s)+fread(s,1,1000000,stdin); 25 return(p1==p2)?EOF:*p1++; 26 } 27 int rd(){ 28 int x=0,f=1;char c=gc(); 29 while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();} 30 while(c>='0'&&c<='9'){x=x*10+c-'0',c=gc();} 31 return x*f; 32 } 33 void pushup(int k){ 34 sum[k]=(sum[ls]+sum[rs]); 35 if(sum[k]>=mod)sum[k]-=mod; 36 } 37 void mfy1(int k,int l,int r,int v){ 38 sum[k]=1ll*sum[k]*v%mod; 39 lz1[k]=1ll*lz1[k]*v%mod; 40 lz2[k]=1ll*lz2[k]*v%mod; 41 } 42 void mfy2(int k,int l,int r,int v){ 43 sum[k]=(sum[k]+1ll*(r-l+1)*v%mod)%mod; 44 lz2[k]=(lz2[k]+v)%mod; 45 } 46 void pushdown(int k,int l,int r){ 47 int mid=(l+r)>>1; 48 if(lz1[k]!=1){ 49 mfy1(ls,l,mid,lz1[k]); 50 mfy1(rs,mid+1,r,lz1[k]); 51 lz1[k]=1; 52 } 53 if(lz2[k]){ 54 mfy2(ls,l,mid,lz2[k]); 55 mfy2(rs,mid+1,r,lz2[k]); 56 lz2[k]=0; 57 } 58 } 59 void build(int k,int l,int r){ 60 lz1[k]=1; lz2[k]=0; 61 if(l==r){sum[k]=rd();return;} 62 int mid=(l+r)>>1; 63 build(ls,l,mid); 64 build(rs,mid+1,r); 65 pushup(k); 66 } 67 void update1(int k,int l,int r,int x,int y,int v){ 68 if(l==x&&r==y)mfy1(k,l,r,v); 69 else{ 70 pushdown(k,l,r); 71 int mid=(l+r)>>1; 72 if(y<=mid)update1(ls,l,mid,x,y,v); 73 else if(x>mid)update1(rs,mid+1,r,x,y,v); 74 else update1(ls,l,mid,x,mid,v),update1(rs,mid+1,r,mid+1,y,v); 75 pushup(k); 76 } 77 } 78 void update2(int k,int l,int r,int x,int y,int v){ 79 if(l==x&&r==y)mfy2(k,l,r,v); 80 else{ 81 pushdown(k,l,r); 82 int mid=(l+r)>>1; 83 if(y<=mid)update2(ls,l,mid,x,y,v); 84 else if(x>mid)update2(rs,mid+1,r,x,y,v); 85 else update2(ls,l,mid,x,mid,v),update2(rs,mid+1,r,mid+1,y,v); 86 pushup(k); 87 } 88 } 89 int query(int k,int l,int r,int x,int y){ 90 if(l==x&&r==y)return sum[k]; 91 else{ 92 pushdown(k,l,r); 93 int mid=(l+r)>>1; 94 if(y<=mid)return query(ls,l,mid,x,y); 95 else if(x>mid)return query(rs,mid+1,r,x,y); 96 else return (query(ls,l,mid,x,mid) + query(rs,mid+1,r,mid+1,y))%mod; 97 } 98 } 99 int main(){ 100 freopen("P3373.in","r",stdin); 101 freopen("P3373.out","w",stdout); 102 n=rd(); m=rd(); mod=rd(); 103 build(1,1,n); 104 for(rg int i=1,op,x,y,v;i<=m;i++){ 105 op=rd(); x=rd(); y=rd(); 106 if(op!=3)v=rd(); 107 if(op==1)update1(1,1,n,x,y,v); 108 else if(op==2)update2(1,1,n,x,y,v); 109 else printf("%d\n",query(1,1,n,x,y)); 110 } 111 return 0; 112 }//by tkys_Austin; 113 114 115 116 117 //分区间的时候注意一下x和y,一不小心就写错; 118 //我,竟然只开了两倍空间。。。。。 119 //20181109 120