C - Just a Hook(写的第一道线段树区间更新的题目,卡了半天)
来源:互联网 发布:网络女神排行 编辑:程序博客网 时间:2024/05/17 04:34
区间更新就是懒惰标志lazy的问题,但是这是我第一道写的,他跟一般的区间更新不同,他不是什么加减,而是直接换了每个数组元素里面的值!!!会区间更新的都应该明白
void pushdown(int node){if(segtree[node].lazy!=0){segtree[node<<1].lazy += segtree[node].lazy;segtree[node<<1|1].lazy += segtree[node].lazy;segtree[node<<1].sum += segtree[node].lazy * (segtree[node<<1].r - segtree[node<<1].l + 1);segtree[node<<1|1].sum += segtree[node].lazy * (segtree[node<<1|1].r - segtree[node<<1|1].l + 1);segtree[node].lazy = 0;}}
这是一般的区间更新,但是你真正弄懂了区间更新后,这个地方还能用+=吗?对于这道题来说,这里四个+=都要改为=!!还有好几个地方都是这个问题!所以照搬模版最无谓,一定理解思想,然后要自己写自己的代码,理解一个思想比做几道题都有用。
接下来是我AC的代码:
#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int Maxn = 100000 + 5;int a[Maxn],val;struct seg{int l,r,sum,lazy;}segtree[Maxn*4];void build(int node,int l,int r){ segtree[node].l=l;segtree[node].r=r;segtree[node].lazy=0; if(l==r) { segtree[node].sum=a[l];return;}else{int mid=(l+r)>>1; build(node<<1,l,mid); build(node<<1|1,mid+1,r); segtree[node].sum = segtree[node<<1].sum + segtree[node<<1|1].sum;}}int query(int node,int x,int y){if(segtree[node].l == x && segtree[node].r == y)//包含在这个[x,y]范围内,直接返回 {return segtree[node].sum;}int mid = segtree[node].l + segtree[node].r;int res = 0;mid >>= 1;if(mid >= y)//[x,y]包含在左子树中 res += query(node<<1,x,y);else if(mid < x)//[x,y]包含在右子树中 res += query(node<<1|1,x,y);else//[x,y]在左右子树都有交集 {res += query(node<<1,x,mid);res += query(node<<1|1,mid+1,y);}return res;}void pushdown(int node){if(segtree[node].lazy!=0){segtree[node<<1].lazy = segtree[node].lazy;segtree[node<<1|1].lazy = segtree[node].lazy;segtree[node<<1].sum = segtree[node].lazy * (segtree[node<<1].r - segtree[node<<1].l + 1);segtree[node<<1|1].sum = segtree[node].lazy * (segtree[node<<1|1].r - segtree[node<<1|1].l + 1);;segtree[node].lazy = 0;}}void update(int node,int x,int y){if(segtree[node].l == x && segtree[node].r == y)//如果node的l和r正好就是这个x和y {segtree[node].lazy = val;//懒惰标记 segtree[node].sum = val * (y - x + 1);//原本都是1,sum是10,都改为2,变成20 return;//先不更新子树,segtree[node].sum已经是正确的了 }if(segtree[node].l == segtree[node].r)//如果已经是树叶节点,就不用pushdown传递lazy下去了。否则访问非法内存空间 return;pushdown(node);//找到一个node的懒惰标记不为0传递下去 int mid = segtree[node].l + segtree[node].r;mid >>= 1;if(mid >= y)update(node<<1,x,y);else if(mid < x)update(node<<1|1,x,y);else//如果卡在两个子树中间各有一段,则两个子树都要更新 {update(node<<1,x,mid);update(node<<1|1,mid+1,y);}segtree[node].sum = segtree[node<<1].sum + segtree[node<<1|1].sum;//更新子树后再来更新自己的sum }int main(){int t,n,q,l,r,i,k=1;scanf("%d",&t);while(t--){scanf("%d",&n);for(i=1;i<=n;i++)a[i] = 1;build(1,1,n);scanf("%d",&q);while(q--){scanf("%d%d%d",&l,&r,&val);update(1,l,r);}printf("Case %d: The total value of the hook is %d.\n",k++,query(1,1,n));}return 0;}
还是要说一句,这题写了至少三个小时,都要崩溃了,但是我还是坚持下来没去看答案自己理解了出来。
0 0
- C - Just a Hook(写的第一道线段树区间更新的题目,卡了半天)
- Just a Hook(线段树区间更新)
- 线段树区间更新 Just a Hook
- Just a Hook ---线段树区间更新
- hdu 1698 Just a Hook(线段树的区间更新及求和)
- HDU 1698 Just a Hook(线段树的区间更新《标记》)
- HDU 1698 Just a Hook(线段树的区间更新)
- HDU 1698 Just a Hook (线段树的区间更新)
- HDU1698 Just a Hook (简单的区间更新线段树)
- HDOJ 题目1698 Just a Hook(线段树区间更新)
- 线段树(区间更新) hdu-1698-Just a Hook
- hdu 1698 Just a Hook(线段树-区间更新)
- HDU 1698 Just a Hook (线段树区间更新)
- HDU 1698 Just a Hook (线段树区间更新)
- HDU 1698 Just a Hook(线段树区间更新)
- HDU1698 - Just a Hook (线段树 区间更新)
- Just a Hook(线段树,区间更新)
- HDU 1698 Just a Hook (线段树,区间更新)
- 自定义带Button的通知,并实现对Button的监听
- 怎么使用class使用hibernate的插入数据到数据库
- ImageView的Scaletype决定了图片在View上显示时的样子,如进行何种比例的缩放,及显示图片的整体还是部分,等等。 设置的方式包括: 1. 在layout xml中定义Android:s
- Data Binding Library(数据绑定库)
- Android Accessibility学习
- C - Just a Hook(写的第一道线段树区间更新的题目,卡了半天)
- 【工具篇】
- Maven学习总结(三)——使用Maven构建项目
- 将hibernate进行简单的优化
- 途娱、汇付、今通、远景面试后记
- 网络流模板(模板题:POJ1273)
- nrf52832 --- softpack安装
- linux3.4.2移植
- iOS学习笔记------UIButton、UIImageView、UILabel的属性与方法