HDU_1698 Just a Hook(线段树+lazy标记)
2015-08-23 21:54
176 查看
题目请点我
题解:
接触到的第一到区间更新,需要用到lazy标记,典型的区间着色问题。
lazy标记详情请参考博客:http://ju.outofmemory.cn/entry/99351
简单讲就是被lazy标记的非叶子节点所包含的所有叶子节点具有相同的性质,当更新或查询到该区间时,不再向下递归,仅对当前节点的lazy标记进行修改。
update :
如果当前区间刚好完全在目的区间内:看当前节点是否被标记,若未被标记,或者被标记了但是与要更新类型相同,不再向下更新,仅标记当前节点;若当前节点已经被标记且与要更新类型不同,执行pushdown操作,标记下移,递归进行更新。
query:
如果当前节点区间在目的区间内(其实一定在,因为题目要求1~N总的价值),若节点被标记,返回segTree[i]*(r+1-l);若当前节点未被标记或者区间不能完全覆盖,递归求解。
代码实现:
题解:
接触到的第一到区间更新,需要用到lazy标记,典型的区间着色问题。
lazy标记详情请参考博客:http://ju.outofmemory.cn/entry/99351
简单讲就是被lazy标记的非叶子节点所包含的所有叶子节点具有相同的性质,当更新或查询到该区间时,不再向下递归,仅对当前节点的lazy标记进行修改。
update :
如果当前区间刚好完全在目的区间内:看当前节点是否被标记,若未被标记,或者被标记了但是与要更新类型相同,不再向下更新,仅标记当前节点;若当前节点已经被标记且与要更新类型不同,执行pushdown操作,标记下移,递归进行更新。
query:
如果当前节点区间在目的区间内(其实一定在,因为题目要求1~N总的价值),若节点被标记,返回segTree[i]*(r+1-l);若当前节点未被标记或者区间不能完全覆盖,递归求解。
代码实现:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #define MAX 100010 #define LCHILD(x) x<<1 #define RCHILD(x) x<<1|1 #define MID(x,y) (x+y)>>1 using namespace std; int T; int res; int N,Q; int segTree[MAX<<2|1]; void pushdown(int root); void build(int root,int l,int r); int query(int a,int b,int l,int r,int root); void update(int a,int b,int l,int r,int root,int type); int main() { scanf("%d",&T); for( int t = 1; t <= T; t++ ){ scanf("%d",&N); scanf("%d",&Q); build(1,1,N); while( Q-- ){ int a,b,c; scanf("%d%d%d",&a,&b,&c); update(a,b,1,N,1,c); } int res = query(1,N,1,N,1); printf("Case %d: The total value of the hook is %d.\n",t,res); } return 0; } void build(int root,int l,int r){ if( l == r ){ segTree[root] = 1; return ; } int mid = MID(l,r); build(LCHILD(root),l,mid); build(RCHILD(root),mid+1,r); //非叶子节点初始为0,表示不标记 segTree[root] = 0; } void update(int a,int b,int l,int r,int root,int type){ //不在当前区间 if( l > b || r < a ){ return ; } //更新区间完全在当前区间内或者type相同 if( (l >= a && r <= b) || segTree[root] == type ){ segTree[root] = type; return ; } //当前节点被标记但是type不同 if( segTree[root] != 0 ){ pushdown(root); } int mid = MID(l,r); update(a,b,l,mid,LCHILD(root),type); update(a,b,mid+1,r,RCHILD(root),type); return ; } int query(int a,int b,int l,int r,int root){ //不在当前区间 if( l > b || r < a ){ return 0; } int mid = MID(l,r); if( l >= a && r <= b ){ if( segTree[root] != 0 ){ //闭区间[l,r] return segTree[root]*(r+1-l); } else{ return query(a,b,l,mid,LCHILD(root))+query(a,b,mid+1,r,RCHILD(root)); } } else{ return query(a,b,l,mid,LCHILD(root))+query(a,b,mid+1,r,RCHILD(root)); } } void pushdown(int root){ segTree[LCHILD(root)] = segTree[root]; segTree[RCHILD(root)] = segTree[root]; segTree[root] = 0; return ; }
相关文章推荐
- 基于jquery的lazy loader插件实现图片的延迟加载[简单使用]
- Lazy Load 延迟加载图片的jQuery插件中文使用文档
- jQuery延迟加载图片插件Lazy Load使用指南
- Spark源码分析(1) 从WordCount示例看Spark延迟计算原理
- 用Scala实现延迟计算
- 线段树题集
- hdu1754
- HDU1394
- 敌兵布阵 (1)
- I Hate It (1)
- LCIS (2)
- A Simple Problem with Integers (2)
- Mayor's posters (3)
- Buy Tickets (3)
- 线段树
- UVA - 12532 Interval Product
- POJ 3264 Balanced Lineup
- C++ 非多线程安全实现Stream Part 1
- hdu 1542 求矩形并的面积
- 关于数据结构之线段树