线段树模板(区间乘混加)
来源:互联网 发布:sftp 命令行 指定端口 编辑:程序博客网 时间:2024/06/10 01:47
https://www.luogu.org/problem/show?pid=3373
#include<iostream>#include<cstring>#include<cstdio>#define M 100000#define LL long longusing namespace std;struct H{ LL sum,l,r,len,addi,tim;}st[4*M+10];//四倍空间LL MOD,n,m,a[M+10];void build(LL o,LL l,LL r){ st[o].l=l,st[o].r=r,st[o].len=r-l+1; if(l==r){st[o].sum=a[l];return;} LL mid=(l+r)>>1; build(o<<1,l,mid); build(o<<1|1,mid+1,r); st[o].sum=(st[o<<1].sum+st[o<<1|1].sum)%MOD; }void pushdown(LL o) //难点{ st[o<<1].sum=((st[o<<1].sum*st[o].tim)%MOD+st[o].addi*st[o<<1].len)%MOD; st[o<<1|1].sum=((st[o<<1|1].sum*st[o].tim)%MOD+st[o].addi*st[o<<1|1].len)%MOD; st[o<<1].addi=((st[o<<1].addi*st[o].tim)%MOD+st[o].addi)%MOD; st[o<<1|1].addi=((st[o<<1|1].addi*st[o].tim)%MOD+st[o].addi)%MOD; st[o<<1].tim=(st[o].tim*st[o<<1].tim)%MOD; st[o<<1|1].tim=(st[o].tim*st[o<<1|1].tim)%MOD; st[o].tim=1,st[o].addi=0;//清空}void tims(LL o,LL l,LL r,LL ql,LL qr,LL t){ int mid=(l+r)>>1; if(ql<=l&&qr>=r) { (st[o].tim*=(t%MOD))%=MOD; (st[o].addi*=(t%MOD))%=MOD; (st[o].sum*=(t%MOD))%=MOD; return; } if(st[o].tim!=1||st[o].addi) pushdown(o);//倍数有0!!! if(ql<=mid) tims(o<<1,l,mid,ql,qr,t); if(qr>mid) tims(o<<1|1,mid+1,r,ql,qr,t); (st[o].sum=(st[o<<1].sum+st[o<<1|1].sum)%MOD)%=MOD; }void add(LL o,LL l,LL r,LL ql,LL qr,LL ax){ int mid=(l+r)>>1; if(ql<=l&&qr>=r){ (st[o].addi+=ax)%=MOD; (st[o].sum+=st[o].len*ax%MOD)%=MOD; return; } if(st[o].addi||st[o].tim!=1) pushdown(o); if(ql<=mid) add(o<<1,l,mid,ql,qr,ax); if(qr>mid) add(o<<1|1,mid+1,r,ql,qr,ax); (st[o].sum=(st[o<<1].sum+st[o<<1|1].sum)%MOD)%=MOD; }LL query(LL o,LL l,LL r,LL ql,LL qr){ int mid=(l+r)>>1; if(ql<=l&&qr>=r) return st[o].sum%MOD; if(st[o].tim!=1||st[o].addi) pushdown(o); LL anss=0; if(ql<=mid) (anss+=query(o<<1,l,mid,ql,qr))%=MOD; if(qr>mid) (anss+=query(o<<1|1,mid+1,r,ql,qr))%=MOD; return anss%MOD; }int main(){ scanf("%lld%lld",&n,&MOD); for(LL i=1;i<=n;i++) scanf("%d",&a[i]); for(LL i=1;i<=4*M;i++) st[i].tim=1; build(1,1,n); scanf("%lld",&m); for(LL i=1;i<=m;i++) { LL p,l,r; LL c; scanf("%lld%lld%lld",&p,&l,&r); if(p==1) { scanf("%lld",&c);//乘c tims(1,1,n,l,r,c); } if(p==2) { scanf("%lld",&c);//加c add(1,1,n,l,r,c); } if(p==3) { LL ans=query(1,1,n,l,r); printf("%lld\n",ans); } } return 0;}
需要注意的问题是,不要溢出;加和乘的关系;取模;倍数有0!
阅读全文
0 1
- 线段树模板(区间乘混加)
- 线段树模板(区间更新)
- 模板:线段树(2)区间修改
- 线段树模板(区间最值)
- ACM_线段树模板(区间更新)
- 线段树 区间求和模板 (区间修改)
- 【模板】线段树 区间加,区间求和 (模板题:P3372线段树1)
- 线段树区间翻转模板
- 线段树 区间更新模板
- [ 模板 ] 线段树区间修改
- 【模板】区间修改-线段树
- 线段树模板 区间加减 区间修改
- [模板]-线段树-区间修改 + 区间查询
- 【模板】树状数组 区间修改,区间求和 (模板题:洛谷P3372线段树1)
- 【模板】线段树 区间加+乘,区间求和 (模板题:洛谷P3373)
- 线段树模板(区间和最大值最下值)
- POJ--3468(线段树,区间修改,模板)
- 线段树求解区间最大最小值(模板)
- 在ubuntu14.04下openni+opencv+kinectV1的学习二:图像的读取与显示
- List元素去重复方法集
- java基础系列--集合类库(一)
- 论编程是吃青春饭的职业。
- SVN官方下载最新版
- 线段树模板(区间乘混加)
- STL
- python 任意一个英文的纯文本文件,统计其中的单词出现的个数
- 多云环境无处不在,但其管理才刚开始
- 百炼-1088-滑雪-C语言-动态规划-记忆化搜索
- 模拟登陆CSDN -- Python爬虫练习之正则表达式和cookie
- 数据库重要知识
- Android开发 第11课 AbsoluteLayout
- Java学习路线图