17AHU排位赛1 D题(线段树除2)
来源:互联网 发布:avi视频合并软件 编辑:程序博客网 时间:2024/06/16 03:37
problem
有一个长度为n的数组a。现有m组操作。
操作1:将区间[l,r]内的所有数字都整除2。
操作2:输出区间[l,r]内所有数字的和。
Input
第一行输入两个整数n,m(1<=n<=200000,1<=m<=200000)
第二行n个整数,表示数组a (0<=a[i]<=10^9)
接下来m行,每行三个整数op,l,r
——若op=1,表示操作1,将[l,r]内所有数字整除2
——若op=2,表示操作2,输出[l,r]内所有数字的和
Output
对于所有的操作2,输出结果。
Sample Input
5 5
3 4 9 2 7
2 3 4
1 4 5
2 1 5
1 3 4
2 3 5
Sample Output
11
20
7
思路
注意到每个数除2求和与求和和除2的结果是不同的,所以lazy标记在这里行不通。(lazy标记就是说整个区间的update先不更新到底,对于本题不更新到底的sum结果是错误的)。
解决办法:不打lazy,更新到点。那这样复杂度不符,注意到一个1e9的数除以2到30次以上就为0,不会改变。
所以令设一个flag数组标记区间里是否都为0,如果是,除法操作根本不用做,sum也不用改变了。于是在复杂度上得到优化。
核心代码
void PushUp(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1]; flag[rt]=flag[rt<<1] | flag[rt<<1|1];//都为0时才为0}void update(int L,int R,int l,int r,int rt){ if(flag[rt]==0) return ;//关键(flag=0表示区间里的数均为0了) if(l==r){ sum[rt]/=2;//除2 flag[rt]=(sum[rt]>0);//更新flag标记 return ; } int m=(l+r)>>1; if(L<=m) update(L,R,lson); if(R>m) update(L,R,rson); PushUp(rt);//不要忘记pushup}
代码示例
#include<iostream>#include<cstdio>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;typedef long long ll;const int maxn=200010;ll sum[maxn<<2];bool flag[maxn<<2];void PushUp(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1]; flag[rt]=flag[rt<<1] | flag[rt<<1|1];//都为0时才为0}void build(int l,int r,int rt){ if(l==r){ scanf("%d",&sum[rt]); flag[rt]=(sum[rt]>0);//大于0 flag为1 return ; } int m=(l+r)>>1; build(lson); build(rson); PushUp(rt);}void update(int L,int R,int l,int r,int rt){ if(flag[rt]==0) return ;//关键(flag=0表示区间里的数均为0了) if(l==r){ sum[rt]/=2;//除2 flag[rt]=(sum[rt]>0);//更新flag标记 return ; } int m=(l+r)>>1; if(L<=m) update(L,R,lson); if(R>m) update(L,R,rson); PushUp(rt);//不要忘记pushup}ll query(int L,int R,int l,int r,int rt){ if(L<=l&&r<=R) return sum[rt]; int m=(l+r)>>1; ll ret=0; if(L<=m) ret+=query(L,R,lson);//这里是求和,也可以维护最值 if(R>m) ret+=query(L,R,rson); return ret;}int main(){ //ios::sync_with_stdio(false); int m,n; scanf("%d %d",&n,&m); build(1,n,1); int op,a,b; for(int i=1;i<=m;++i){ scanf("%d %d %d",&op,&a,&b); if(op==1){ update(a,b,1,n,1); } else{ printf("%lld\n",query(a,b,1,n,1)); } } return 0;}
阅读全文
1 0
- 17AHU排位赛1 D题(线段树除2)
- 17AHU排位赛3 D题 旋转吧!雪月花 ! (DFS序,线段树维护树上最值)
- 17AHU排位赛2 F题(bitset优化)
- 17AHU排位赛1 C题(经典DP)
- 17AHU排位赛2 A题(最小生成树、LCA维护树上路径)
- 17AHU排位赛1 E题(gcd>1序列,容斥)
- 17AHU排位赛3 C题 (LCS)
- 17AHU排位赛2 E题(树上最大匹配,树形DP)
- 17AHU排位赛3 A题 (逆康托展开)
- CF413E Maze 2D(线段树)
- Codeforces Round #275 (Div. 2) D题 (线段树)
- Codeforces 19 D. Points(线段树&set好题)
- 线段树(good)Codeforces Round #275 (Div. 2)D
- Codeforces Round #365 (Div. 2) D (线段树)
- 17AHU排位赛3 G题 (n的k次方的因子数)
- 17AHU排位赛3 F题 (多路归并求第k大和)
- Codeforces Round #426 (Div. 2) D. The Bakery(DP+线段树) 好题
- Codeforces Round #426(Div.2)D题 DP+线段树
- muduo源码学习(18)-EventLoopThread
- Change Internal ID of ODI Repository. (ODI-10093: You are importing an object from another)
- 18、oracle:存储过程
- 对象序列化的应用,一个文件中存储多个对象
- Velocity.js的使用
- 17AHU排位赛1 D题(线段树除2)
- 剑指offer_链表---复杂链表的复制
- TCP 拥塞控制和流量控制
- quartz_properties文件配置之主要配置
- python库学习笔记——re库:正则表达式入门(一)
- Android数据存储(二)---Sqlite数据库(上)
- 开发人员必备技能:单元测试
- 一天
- java开发_eclipse导出为war文件,热部署到tomcat运行总结