bzoj1798[Ahoi2009]Seq 维护序列seq
题意:
维护序列,支持区间加、区间乘、区间求和模一个数。序列大小和操作数≤100000
题解:
线段树,加标记和乘标记的处理同bzoj4003。模的时候注意细节。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define inc(i,j,k) for(int i=j;i<=k;i++) 5 #define maxn 100010 6 #define ll long long 7 using namespace std; 8 9 int n,m; ll sm[maxn*3],tgpl[maxn*3],tgmu[maxn*3],v[maxn],p; bool iss[maxn*3]; 10 inline int read(){ 11 char ch=getchar(); int f=1,x=0; 12 while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} 13 while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); 14 return f*x; 15 } 16 void pushdown(int x,int l,int r){ 17 if(tgmu[x]!=1||tgpl[x]!=0){ 18 if(!iss[x]){ 19 int lc=x<<1,rc=x<<1|1; int mid=l+r>>1; 20 sm[lc]=(sm[lc]*tgmu[x]%p+tgpl[x]*(mid-l+1)%p)%p; 21 sm[rc]=(sm[rc]*tgmu[x]%p+tgpl[x]*(r-mid)%p)%p; 22 tgmu[lc]=tgmu[lc]*tgmu[x]%p; tgmu[rc]=tgmu[rc]*tgmu[x]%p; 23 tgpl[lc]=(tgpl[lc]*tgmu[x]%p+tgpl[x])%p; tgpl[rc]=(tgpl[rc]*tgmu[x]%p+tgpl[x])%p; 24 } 25 tgpl[x]=0; tgmu[x]=1; 26 } 27 } 28 int update(int x){ 29 if(!iss[x])sm[x]=(sm[x<<1]+sm[x<<1|1])%p; 30 } 31 void build(int x,int l,int r){ 32 tgmu[x]=1; if(l==r){sm[x]=v[l]; iss[x]=1; return;} int mid=l+r>>1; iss[x]=0; 33 build(x<<1,l,mid); build(x<<1|1,mid+1,r); update(x); 34 } 35 void modmu(int x,int l,int r,int ql,int qr,ll val){ 36 pushdown(x,l,r); 37 if(ql<=l&&r<=qr){ 38 sm[x]=sm[x]*val%p; tgmu[x]=tgmu[x]*val%p; tgpl[x]=tgpl[x]*val%p; return; 39 } 40 int mid=l+r>>1; 41 if(ql<=mid)modmu(x<<1,l,mid,ql,qr,val); if(mid<qr)modmu(x<<1|1,mid+1,r,ql,qr,val); 42 update(x); 43 } 44 void modpl(int x,int l,int r,int ql,int qr,ll val){ 45 pushdown(x,l,r); 46 if(ql<=l&&r<=qr){ 47 sm[x]=(sm[x]+val*(r-l+1)%p)%p; tgpl[x]=(tgpl[x]+val)%p; return; 48 } 49 int mid=l+r>>1; 50 if(ql<=mid)modpl(x<<1,l,mid,ql,qr,val); if(mid<qr)modpl(x<<1|1,mid+1,r,ql,qr,val); 51 update(x); 52 } 53 ll query(int x,int l,int r,int ql,int qr){ 54 pushdown(x,l,r); 55 if(ql<=l&&r<=qr)return sm[x]; int mid=l+r>>1; ll q=0; 56 if(ql<=mid)q=(q+query(x<<1,l,mid,ql,qr))%p; 57 if(mid<qr)q=(q+query(x<<1|1,mid+1,r,ql,qr))%p; return q; 58 } 59 int main(){ 60 n=read(); p=read(); inc(i,1,n)v[i]=read()%p; build(1,1,n); m=read(); 61 inc(i,1,m){ 62 int opt=read(); 63 if(opt==1){ 64 int x=read(),y=read(); ll z=read()%p; modmu(1,1,n,x,y,z); 65 } 66 if(opt==2){ 67 int x=read(),y=read(); ll z=read()%p; modpl(1,1,n,x,y,z); 68 } 69 if(opt==3){ 70 int x=read(),y=read(); printf("%lld\n",query(1,1,n,x,y)%p); 71 } 72 } 73 return 0; 74 }
20160714