BZOJ 1798: [Ahoi2009]Seq 维护序列seq

来源:互联网 发布:原油api数据影响 编辑:程序博客网 时间:2024/06/06 09:49

一眼就能看出来用线段树做

只是我太菜了,因为有两个标记调了好久才出样例,一次就过还是很开心的

#include<cstdio>#define ls (x<<1)#define rs ((x<<1)+1)#define mid ((l+r)>>1)#define C (c=getchar())#define LL long longusing namespace std;struct T{LL sum,a1,a2;//a1-乘法标记,a2-加法标记 }t[400050];LL wyx,mul,add;inline LL read(LL &a){static char c;a=0;C;while(c<'0'||c>'9')C;while(c>='0'&&c<='9')a=a*10+c-'0',C;}inline int read(int &a){static char c;a=0;C;while(c<'0'||c>'9')C;while(c>='0'&&c<='9')a=a*10+c-'0',C;}inline void update(int x){t[x].sum=(t[ls].sum+t[rs].sum)%wyx;}inline void push(int x,int num){t[ls].sum=(t[ls].sum*t[x].a1+(num-(num>>1))*t[x].a2)%wyx;t[ls].a1=t[ls].a1*t[x].a1%wyx;t[ls].a2=(t[ls].a2*t[x].a1+t[x].a2)%wyx;t[rs].sum=(t[rs].sum*t[x].a1+(num>>1)*t[x].a2)%wyx;t[rs].a1=t[rs].a1*t[x].a1%wyx;t[rs].a2=(t[rs].a2*t[x].a1+t[x].a2)%wyx;t[x].a1=1,t[x].a2=0;}void build(int x,int l,int r){t[x].a1=1,t[x].a2=0;if(l==r){read(t[x].sum);return;}build(ls,l,mid);build(rs,mid+1,r);update(x);}void change(int x,int l,int r,int lt,int rt){if(l>rt||r<lt)return;if(l>=lt&&r<=rt){t[x].sum=(t[x].sum*mul+(r-l+1)*add)%wyx;t[x].a1=(t[x].a1*mul)%wyx;t[x].a2=(t[x].a2*mul+add)%wyx;return;}push(x,r-l+1);change(ls,l,mid,lt,rt);change(rs,mid+1,r,lt,rt);update(x);}LL ask(int x,int l,int r,int lt,int rt){if(l>rt||r<lt)return 0;if(l>=lt&&r<=rt)return t[x].sum;push(x,r-l+1);LL ans=(ask(ls,l,mid,lt,rt)+ask(rs,mid+1,r,lt,rt))%wyx;update(x);return ans;}LL n,m;int main(){read(n),read(wyx);build(1,1,n);read(m);int tp,l,r;for(int i=1;i<=m;++i){read(tp);if(tp==1){read(l),read(r),read(mul),add=0;change(1,1,n,l,r);}elseif(tp==2){read(l),read(r);mul=1,read(add);change(1,1,n,l,r);}elseif(tp==3){read(l),read(r);printf("%lld\n",ask(1,1,n,l,r));}}return 0;}

0 0
原创粉丝点击