洛谷P2023 [AHOI2009]维护序列 (BZOJ1798)
2017-11-09 13:51
260 查看
线段树
洛谷题目传送门BZOJ题目传送门
裸的双Tag线段树。。。(不过我都没打过双Tag的线段树)
BZOJMLE说我TLE。。。害我郁闷了半天。。。
注意BZOJ只给64MB
还有就是一定要先乘后加
具体见注释
代码:
#include<cctype> #include<cstdio> #include<cstring> #include<algorithm> #define MAXN 150000 using namespace std; typedef long long LL;//开LL保险一点 struct tree{ LL l,r; LL sum; }t[MAXN*4+5]; LL n,m,MOD; LL a[MAXN+5],lazy1[MAXN*4+5],lazy2[MAXN*4+5];//1表示加,2表示乘 inline char readc(){//fread读优 static char buf[100000],*l=buf,*r=buf; if (l==r) r=(l=buf)+fread(buf,1,100000,stdin); if (l==r) return EOF; return *l++; } inline LL _read(){ LL num=0; char ch=readc(); while (!isdigit(ch)) ch=readc(); while (isdigit(ch)) { num=num*10+ch-48; ch=readc(); } return num; } void build(LL l,LL r,LL num){//建树 t[num].l=l,t[num].r=r; if (l==r){//给叶子结点赋值 t[num].sum=a[l]; return; } build(l,(l+r)/2,num*2); build((l+r)/2+1,r,num*2+1); t[num].sum=(t[num*2].sum+t[num*2+1].sum)%MOD; } void pushdown(LL num){//传Tag if (lazy2[num]!=1){//先算乘法 (lazy2[num*2]*=lazy2[num])%=MOD; (lazy2[num*2+1]*=lazy2[num])%=MOD; t[num*2].sum=(t[num*2].sum*lazy2[num])%MOD; t[num*2+1].sum=(t[num*2+1].sum*lazy2[num])%MOD; (lazy1[num*2]*=lazy2[num])%=MOD; (lazy1[num*2+1]*=lazy2[num])%=MOD; lazy2[num]=1;//清1 } if (lazy1[num]){//再算加法 (lazy1[num*2]+=lazy1[num])%=MOD; (lazy1[num*2+1]+=lazy1[num])%=MOD; (t[num*2].sum+=((t[num*2].r-t[num*2].l+1)*lazy1[num])%MOD)%=MOD; (t[num*2+1].sum+=((t[num*2+1].r-t[num*2+1].l+1)*lazy1[num])%MOD)%=MOD; lazy1[num]=0;//清0 } } void nsrt(LL l,LL r,LL w,bool flag,LL num){//插入(修改) if (t[num].l>=l&&t[num].r<=r){ if (!flag){//如果是乘操作 t[num].sum=(t[num].sum*w)%MOD; lazy2[num]=(lazy2[num]*w)%MOD; lazy1[num]=(lazy1[num]*w)%MOD;//别忘了给加Tag乘 } else{ t[num].sum=(t[num].sum+((t[num].r-t[num].l+1)*w)%MOD)%MOD; lazy1[num]=(lazy1[num]+w)%MOD; } return; } if (t[num].l>r||t[num].r<l) return; if (lazy1[num]||lazy2[num]!=1) pushdown(num); nsrt(l,r,w,flag,num*2); nsrt(l,r,w,flag,num*2+1); t[num].sum=(t[num*2].sum+t[num*2+1].sum)%MOD; } LL srch(LL l,LL r,LL num){ if (t[num].l>=l&&t[num].r<=r) return t[num].sum; if (t[num].r<l||t[num].l>r) return 0; if (lazy1[num]||lazy2[num]!=1) pushdown(num); LL x=srch(l,r,num*2); LL y=srch(l,r,num*2+1); return (x+y)%MOD; } int main(){ n=_read(),MOD=_read(); for (LL i=1;i<=n;i++) a[i]=(_read())%MOD; m=_read(); for (LL i=1;i<=MAXN*4;i++) lazy2[i]=1; build(1,n,1); while (m--){ LL flag=_read(); switch (flag){ case 1:{ LL l=_read(),r=_read(),w=_read(); nsrt(l,r,w,0,1); break; } case 2:{ LL l=_read(),r=_read(),w=_read(); nsrt(l,r,w,1,1); break; } default:{ LL l=_read(),r=_read(); printf("%d\n",srch(l,r,1)); break; } } } return 0; }
相关文章推荐
- BZOJ1798: [Ahoi2009]Seq 维护序列seq
- bzoj1798: [Ahoi2009]Seq 维护序列seq 2011-12-20
- 洛谷P2023 [AHOI2009]维护序列
- AHOI 2009 (BZOJ1798)维护序列 seq (线段树好题?)
- AHOI 2009 (BZOJ1798)维护序列 seq (线段树好题?)
- BZOJ1798 洛谷P2023 [AHOI2009]维护序列
- bzoj1798: [Ahoi2009]Seq 维护序列seq 线段树
- BZOJ1798: [Ahoi2009]Seq 维护序列seq
- 【bzoj1798】【洛谷P2023】【AHOI2009】维护序列
- bzoj1798 [AHOI2009]维护序列(线段树)
- 洛谷P2023 && bzoj1798 [AHOI2009]维护序列
- BZOJ1798: [Ahoi2009]Seq 维护序列seq
- 洛谷P2023 [AHOI2009]维护序列
- BZOJ 1798: [Ahoi2009]Seq 维护序列seq (线段树)
- [bzoj1798][codevs2216][luogu2023][Ahoi2009]维护序列
- 【BZOJ】1798: [Ahoi2009]Seq 维护序列seq(线段树)
- AC日记——[Ahoi2009]Seq 维护序列seq bzoj 1798
- 【BZOJ】1798 [Ahoi2009]Seq 维护序列seq
- 洛谷2023 [AHOI2009]维护序列 线段树+双lazy
- 【bzoj 1798】[AHOI2009]维护序列