bzoj1798[Ahoi2009]Seq 维护序列seq

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

posted @ 2016-07-14 20:47  YuanZiming  阅读(154)  评论(0编辑  收藏  举报