线段树(区间更新) hdu-1698-Just a Hook
2013-04-05 15:22
246 查看
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1698
题目意思:
有n个棒子,每个棒子都有一个值,q个更新,每次更新时有三个参数x,y,z表示,把x-y区间内的棒子的值改成z,为最后所有棒子的值的总和是多少。
解题思路:
建一个n大小的线段树,用sum[rt]表示该节点区间的值总和,value[rt]表示该区间当前所处的状态,如果为非零则表示该区间内所有棒子为该值,并且没有传下去,如果为零,说明该区间内的状态改变都已传下去了。每次更新完毕后将该区间的sum值求出(向上更新),最后输出sum[1]即可。
关键:更新延迟,不是每次更新都更新到叶子节点,记录状态等下次更新时再往下更新,但每次都把顶层的sum值给求出来。
详见代码:
http://acm.hdu.edu.cn/showproblem.php?pid=1698
题目意思:
有n个棒子,每个棒子都有一个值,q个更新,每次更新时有三个参数x,y,z表示,把x-y区间内的棒子的值改成z,为最后所有棒子的值的总和是多少。
解题思路:
建一个n大小的线段树,用sum[rt]表示该节点区间的值总和,value[rt]表示该区间当前所处的状态,如果为非零则表示该区间内所有棒子为该值,并且没有传下去,如果为零,说明该区间内的状态改变都已传下去了。每次更新完毕后将该区间的sum值求出(向上更新),最后输出sum[1]即可。
关键:更新延迟,不是每次更新都更新到叶子节点,记录状态等下次更新时再往下更新,但每次都把顶层的sum值给求出来。
详见代码:
#include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<algorithm> #include<vector> #include<map> #include<stack> #include<list> #include<queue> #define eps 1e-6 #define INF (1<<30) #define PI acos(-1.0) using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,(rt<<1)|1 #define maxn 110000 int sum[maxn*4],value[maxn*4]; //作为标记如果为非零则表示没有向下传 /* freopen("data.in","r",stdin); freopen("data.out","w",stdout); */ void pushup(int rt) { sum[rt]=sum[rt<<1]+sum[rt<<1|1]; return ; } void build(int l,int r,int rt) { value[rt]=0; //不需往下传 sum[rt]=1;//叶子节点,开始均为铜1 if(l==r) return ; int m=(l+r)>>1; build(lson); build(rson); pushup(rt); return ; } void pushdown(int rt,int num) //向下传,num为该区间点的总的个数 { if(value[rt]) { value[rt<<1]=value[rt<<1|1]=value[rt]; sum[rt<<1]=(num-(num>>1))*value[rt]; //注意前一区间可能后一区间多一,所以前一区间可能比后面多一个 sum[rt<<1|1]=(num>>1)*value[rt]; value[rt]=0;//表示该节点以向下更新,下次不必下传了 } return ; } void update(int L,int R,int v,int l,int r,int rt) { if(L<=l&&R>=r) //如果要查找的区间包括当前空间,就不往下更新了,保存 { value[rt]=v; sum[rt]=v*(r-l+1); return ; } //如果不能包括该区间,说明要分,先将上次的传下去 pushdown(rt,r-l+1); int m=(l+r)>>1; if(L<=m) update(L,R,v,lson);//必须更新左边 if(R>m) update(L,R,v,rson);//必须更新右边 pushup(rt); //向上传 return ; } int main() { int ca,n,q; scanf("%d",&ca); for(int k=1;k<=ca;k++) { scanf("%d%d",&n,&q); build(1,n,1); while(q--) { int a,b,c; scanf("%d%d%d",&a,&b,&c); update(a,b,c,1,n,1); } printf("Case %d: The total value of the hook is %d.\n",k,sum[1]); } return 0; }
相关文章推荐
- 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 线段树区间更新(值进行覆盖)
- 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 线段树区间更新
- 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(线段树区间更新)
- hdu 1698 Just a Hook 线段树区间更新
- hdu 1698 Just a Hook(线段树-区间更新)
- Just a Hook (HDU_1698) 线段树+区间更新
- HDU 1698 Just a Hook 线段树区间更新(值进行覆盖)
- HDU 1698 Just a Hook(线段树 区间更新 + 查询区间和)