bzoj1798: [Ahoi2009]Seq 维护序列seq
来水一发。
当然也不完全是为了水,这题的对于乘法和加法的处理还是值得考虑的;
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<algorithm> using namespace std; #define LL unsigned long long #define FILE "dealing" #define up(i,j,n) for(LL i=(j);i<=(n);i++) LL read(){ int ch=getchar(),f=1,x=0; while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch<='9'&&ch>='0')x=(x<<1)+(x<<3)+ch-'0',ch=getchar(); return f*x; } const LL maxn=400100,inf=1000000000; LL n,m,mod; LL a[maxn]; LL x,y,c; LL sum[maxn],ch[maxn],del[maxn]; void cheng(LL x,LL c){ch[x]=(ch[x]*c)%mod;del[x]=(del[x]*c)%mod;sum[x]=(sum[x]*c)%mod;} void jian(LL x,LL siz,LL c){del[x]=(del[x]+c)%mod;sum[x]=(sum[x]+c*siz)%mod;} void pushdown(LL x,LL l,LL r){ if(ch[x]!=1)cheng(x<<1,ch[x]),cheng(x<<1|1,ch[x]),ch[x]=1; if(del[x]){jian(x<<1,((l+r)>>1)-l+1,del[x]);jian(x<<1|1,r-((l+r)>>1),del[x]);del[x]=0;} } void updata(LL x){sum[x]=(sum[x<<1]+sum[x<<1|1])%mod;} LL query(LL l,LL r,LL rt){ if(l>y||r<x)return 0; if(l>=x&&r<=y)return sum[rt]; pushdown(rt,l,r); return (query(l,((l+r)>>1),rt<<1)+query(((l+r)>>1)+1,r,rt<<1|1))%mod; } void change(LL l,LL r,LL rt){ if(l>y||r<x)return; if(l>=x&&r<=y){cheng(rt,c);return;} pushdown(rt,l,r); change(l,((l+r)>>1),rt<<1);change(((l+r)>>1)+1,r,rt<<1|1); updata(rt); } void Change(LL l,LL r,LL rt){ if(l>y||r<x)return; if(l>=x&&r<=y){jian(rt,r-l+1,c);return;} pushdown(rt,l,r); Change(l,((l+r)>>1),rt<<1);Change(((l+r)>>1)+1,r,rt<<1|1); updata(rt); } void build(LL l,LL r,LL rt){ ch[rt]=1; if(l==r){sum[rt]=a[l];return;} build(l,(((l+r)>>1)),rt<<1); build(((l+r)>>1)+1,r,rt<<1|1); updata(rt); } int main(){ n=read(),mod=read(); up(i,1,n)a[i]=read(); build(1,n,1); m=read(); while(m--){ LL ch=read(); if(ch==1){ x=read(),y=read(),c=read(); change(1,n,1); } if(ch==2){ x=read(),y=read(),c=read(); Change(1,n,1); } if(ch==3){ x=read(),y=read(); printf("%lld\n",query(1,n,1)); } } return 0; }