洛谷P2023 [AHOI2009]维护序列 (BZOJ1798)
来源:互联网 发布:白金数据 高清 网盘 编辑:程序博客网 时间:2024/05/29 09:59
线段树
洛谷题目传送门
BZOJ题目传送门
裸的双Tag线段树。。。(不过我都没打过双Tag的线段树)
BZOJMLE说我TLE。。。害我郁闷了半天。。。
注意BZOJ只给64MB
还有就是一定要先乘后加
具体见注释
代码:
#include<cctype>#include<cstdio>#include<cstring>#include<algorithm>#define MAXN 150000using 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;}
阅读全文
0 0
- 洛谷P2023 [AHOI2009]维护序列 (BZOJ1798)
- 【bzoj1798】【洛谷P2023】【AHOI2009】维护序列
- BZOJ1798 洛谷P2023 [AHOI2009]维护序列
- 洛谷P2023 && bzoj1798 [AHOI2009]维护序列
- 洛谷P2023 [AHOI2009]维护序列
- [P2023][AHOI2009]维护序列
- [洛谷luogu] P2023 [AHOI2009]维护序列
- bzoj1798【ahoi2009】维护序列
- 【AHOI2009】bzoj1798 维护序列
- 【BZOJ1798】【AHOI2009】维护序列
- bzoj1798 [AHOI2009]维护序列(线段树)
- 洛谷 P2023 [AHOI2009]维护序列(bzoj P1798 [Ahoi2009]Seq 维护序列seq)
- P2023 [AHOI2009]维护序列 --线段树
- bzoj1798: [Ahoi2009]Seq 维护序列seq(线段树)
- 【bzoj1798】[Ahoi2009]Seq 维护序列seq
- bzoj1798[Ahoi2009]Seq 维护序列seq
- [BZOJ1798]AHOI2009 维护序列|线段树|splay
- [BZOJ1798][Ahoi2009]Seq 维护序列seq
- 前端工程——基础篇
- sort排序
- Sqoop导入hive注意事项
- Java Map中的几个常见问题
- 全面了解R语言中的k-means如何聚类?
- 洛谷P2023 [AHOI2009]维护序列 (BZOJ1798)
- Zookeeper问题汇总
- canvas绘制动态时钟
- 重磅 | 腾讯提出共享AI,抢先布局游戏与多媒体AI,首秀同声传译
- 【程序员周边】程序员系列表情包
- 11.9第7节课
- Javascript的学习心得
- Python 3.6 类属性
- 11月7日云栖精选夜读:阿里巴巴风鸣:做技术Leader要有危机意识