线段树模板(区间修改)——hdu1698
2017-10-09 19:31
441 查看
题目链接:https://vjudge.net/problem/HDU-1698
题目意思:有T组样例,每组样例给出n个棍子,开始棍子价值都是1,给出q个操作,可以把编号【x,y】之间的棍子的值改为z(z可以是1,2,3),求最终总价值。
分析:线段树区间修改,比较点修改,多了一个addv数组,该数组的意义在于可以记录修改的值。注意理解一个区间内其和为addv[rt]*(l-r+1),意义是改变值与区间长度的乘积,这样区间的和便化为区间内点值得和。区间修改不同于点修改,区间修改会影响许多节点,点修改则只影响其一个节点
代码如下:
题目意思:有T组样例,每组样例给出n个棍子,开始棍子价值都是1,给出q个操作,可以把编号【x,y】之间的棍子的值改为z(z可以是1,2,3),求最终总价值。
分析:线段树区间修改,比较点修改,多了一个addv数组,该数组的意义在于可以记录修改的值。注意理解一个区间内其和为addv[rt]*(l-r+1),意义是改变值与区间长度的乘积,这样区间的和便化为区间内点值得和。区间修改不同于点修改,区间修改会影响许多节点,点修改则只影响其一个节点
代码如下:
#include <iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; const int maxn=100000+5; int addv[maxn<<2]; int sum[maxn<<2]; //改变[l,r]区间内其子节点的addv值和sum值 void pushdown(int rt,int l,int r) { int m=(l+r)>>1; if(addv[rt]) { //本节点需要被标记才能箱子传递 addv[rt<<1]=addv[rt<<1|1]=addv[rt]; //子节点区间和父节点addv值相同 sum[rt<<1]=addv[rt<<1]*(m-l+1);//sum值=addv值*区间长度 sum[rt<<1|1]=addv[rt<<1|1]*(r-m); addv[rt]=0; //取消标记 } } //建树 void build(int l,int r,int rt) { addv[rt]=0; //比点修改多了一处 if(l==r) { //叶节点赋值 sum[rt]=1; return ; } int m=(l+r)>>1; build(l,m,rt<<1); //向左走 build(m+1,r,rt<<1|1);//向右走 sum[rt]=sum[rt<<1]+sum[rt<<1|1];//更新sum值 } //更新区间值 void update(int ll,int rr,int c,int l,int r,int rt) { if(ll<=l&&rr>=r) { //叶节点直接更新 addv[rt]=c; sum[rt]=addv[rt]*(r-l+1); return ; } pushdown(rt,l,r); //需要向下传递 int m=(l+r)>>1; if(ll<=m)update(ll,rr,c,l,m,rt<<1); if(rr>m)update(ll,rr,c,m+1,r,rt<<1|1); sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } //查询,和点修改类似 int query(int ll,int rr,int l,int r,int rt) { if(ll<=l&&rr>=r) { return sum[rt]; } int m=(l+r)>>1; int res=0; if(ll<=m)res+=query(ll,rr,l,m,rt<<1); if(rr>m)res+=query(ll,rr,m+1,r,rt<<1|1); return res; } int main() { int T; scanf("%d",&T); int kase=0; while(T--) { int n,q; scanf("%d%d",&n,&q); build(1,n,1); for(int i=0; i<q; i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); update(x,y,z,1,n,1); } printf("Case %d: The total value of the hook is %d.\n",++kase,sum[1]); } }
相关文章推荐
- 线段树 区间求和模板 (区间修改)
- hdu 1166 线段树 单点修改 + 询问区间求和 (线段树模板)
- [模板]-线段树-区间修改 + 区间查询
- hdu1698 Just a Hook (线段树区间修改)
- hdu1698(线段树区间更新模板)
- NOIP算法每周过之 线段树 区间 区间修改 区间查值 模板
- 题集+模板:线段树[1]点修改 区间查找 hdu 2795+1394+1754+4302
- 模板:线段树(2)区间修改
- hdu1698 Just a Hook(线段树区间修改)
- I Hate It HDU - 1754(线段树单点修改,区间求最大值模板)
- A Simple Problem with Integers(线段树+区间修改+区间询问模板)
- hdu1698 Just a Hook(线段树区间修改)
- POJ_3468 A Simple Problem with Integers(线段树区间修改+附线段树模板)
- 线段树模板(点修改 ,区间查询)
- 模板——线段树(区间修改)
- [ 模板 ] 线段树区间修改
- 线段树模板 区间加减 区间修改
- 线段树区间更新(2)(lazy)(区间都变为v)(序号从1开始)(O(logn))模板(hdu1698)
- 线段树区间修改模板
- 线段树模板 区间加减 区间修改