线段树lazy标记2
来源:互联网 发布:centos nfs samba 编辑:程序博客网 时间:2024/06/05 01:03
Description
给定一个正整数序列
1):ADD
2):COVER
3):QUERY
Input
第一行两个正整数
第二行
接下来的
Output
对于每个询问操作,输出答案。
Sample Input
10 10
17 18 16 12 13 7 13 6 11 20
QUERY 5 6
QUERY 2 7
ADD 1 6 13
QUERY 4 10
ADD 2 5 18
COVER 2 8 11
ADD 6 9 5
QUERY 8 8
ADD 6 9 18
QUERY 5 7
Sample Output
20
79
121
16
79
HINT
思路
记录3个标记:
代码
#include <cstdio>const int maxn=100000;long long a[maxn+10];struct segment_tree{ long long val[(maxn<<2)+10],sum[(maxn<<2)+10],cover[(maxn<<2)+10]; int icover[(maxn<<2)+10]; inline int updata(int now)//更新这个点的val { val[now]=val[now<<1]+val[now<<1|1]; return val[now]; } inline int pushdown(int now,int left,int right)//下传标记 { int mid=(left+right)>>1; if(icover[now])//如果这个点被cover过,下传cover标记 { icover[now]=0; cover[now<<1]=cover[now]; sum[now<<1]=0;//注意sum标记要赋成0 val[now<<1]=cover[now]*(mid-left+1); cover[now<<1|1]=cover[now]; sum[now<<1|1]=0; val[now<<1|1]=cover[now]*(right-mid); icover[now<<1]=icover[now<<1|1]=1;//表示被覆盖过 } sum[now<<1]+=sum[now];//下传sum标记 val[now<<1]+=sum[now]*(mid-left+1); sum[now<<1|1]+=sum[now]; val[now<<1|1]+=sum[now]*(right-mid); sum[now]=0; return 0; } int build(int now,int left,int right)//建树 { if(left==right) { icover[now]=0;//初始化 sum[now]=0; val[now]=a[left]; return 0; } int mid=(left+right)>>1; build(now<<1,left,mid); build(now<<1|1,mid+1,right); updata(now); return 0; } int rcover(int now,int left,int right,int askl,int askr,long long cval) //将一个区间[left,right]cover成cval { if((askl<=left)&&(right<=askr)) { icover[now]=1;//覆盖 cover[now]=cval; sum[now]=0;//注意 val[now]=cval*(right-left+1); return 0; } int mid=(left+right)>>1; pushdown(now,left,right); if(askl<=mid) { rcover(now<<1,left,mid,askl,askr,cval); } if(mid<askr) { rcover(now<<1|1,mid+1,right,askl,askr,cval); } updata(now); return 0; } int add(int now,int left,int right,int askl,int askr,long long cval) //将一个区间的值增加 { if((askl<=left)&&(right<=askr)) { sum[now]+=cval; val[now]+=cval*(right-left+1); return 0; } int mid=(left+right)>>1; pushdown(now,left,right); if(askl<=mid) { add(now<<1,left,mid,askl,askr,cval); } if(mid<askr) { add(now<<1|1,mid+1,right,askl,askr,cval); } updata(now); return 0; } long long getsum(int now,int left,int right,int askl,int askr) //求一段区间的和 { if((askl<=left)&&(right<=askr)) { return val[now]; } int mid=(left+right)>>1; long long res=0; pushdown(now,left,right); if(askl<=mid) { res+=getsum(now<<1,left,mid,askl,askr); } if(mid<askr) { res+=getsum(now<<1|1,mid+1,right,askl,askr); } return res; }};segment_tree st;int n,m,aa,b;long long c;char s[10];int main(){ scanf("%d%d",&n,&m); for(register int i=1; i<=n; ++i) { scanf("%lld",&a[i]); } st.build(1,1,n); while(m--) { scanf("%s%d%d",s,&aa,&b); if(s[0]=='Q') { printf("%lld\n",st.getsum(1,1,n,aa,b)); } else if(s[0]=='C') { scanf("%lld",&c); st.rcover(1,1,n,aa,b,c); } else { scanf("%lld",&c); st.add(1,1,n,aa,b,c); } } return 0;}
阅读全文
0 0
- 线段树lazy标记2
- 线段树lazy标记
- 线段树lazy标记??Hdu4902
- Transformation(线段树 + lazy 标记)
- poj 3225 线段树注意lazy标记
- POJ 3468 线段树+lazy标记
- bzoj 1798 线段树 双lazy标记
- hdu 4578 线段树lazy标记
- 线段树区间修改 lazy标记 大法
- 线段树lazy标记1血题
- POJ3468 线段树 + Lazy Tag (延迟标记)
- poj1436(线段树lazy标记)
- POJ 3225 线段树+lazy标记
- 还教室(线段树lazy标记)
- 线段树lazy标记入门笔记
- poj 3468 线段树 lazy标记模板
- 线段树lazy标记永久化
- 线段树模板(lazy标记)ZOJ 3686
- Ubuntu 下的定时人物at\crontab等使用
- maven导出项目依赖的jar包和解决-Dmaven.multiModuleProjectDirectory system property is not set. Check $M2_HOME en
- JavaWeb自主学习--css(二),day2
- ThreadPoolExecutor线程池
- Abstractive Document Summarization with a Graph-Based Attentional Neural Model
- 线段树lazy标记2
- 三、Spring Boot微服务构建
- Android之网络编程OkHttp3用法全解析
- Dynamic RegEx based Python
- python列表元组字典
- 树结构
- ES6 let和const命令
- 32位单精度浮点数表示法
- 产品经理不再纸上谈兵——App登录设计的再思考