HDU 3974 Assign the task (DFS序 + 线段树)
2016-04-06 16:00
288 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3974
给你T组数据,n个节点,n-1对关系,右边的是左边的父节点,所有的值初始化为-1,然后给你q个操作:
有两种操作:
操作一:T X Y ,将以X为根的子树上的所有节点都变成Y。
操作二:C X,查询第X号点是多少?
没想到是线段树做,就算想到了也想不到用dfs序做...
例子中给你了这样的树:
2
/ \
3 5
/ \
4 1
DFS一遍转化成DFS序:2344113552
然后记录下每个数字最左边和最右边的位置,如:left[3] = 2, right[3] = 7。
因为是DFS序,所以他的子节点的范围一定包含在他的左右位置中。
所以就变成了很明显的线段树成段更新...
注意一点的是,查询是单点更新...
给你T组数据,n个节点,n-1对关系,右边的是左边的父节点,所有的值初始化为-1,然后给你q个操作:
有两种操作:
操作一:T X Y ,将以X为根的子树上的所有节点都变成Y。
操作二:C X,查询第X号点是多少?
没想到是线段树做,就算想到了也想不到用dfs序做...
例子中给你了这样的树:
2
/ \
3 5
/ \
4 1
DFS一遍转化成DFS序:2344113552
然后记录下每个数字最左边和最右边的位置,如:left[3] = 2, right[3] = 7。
因为是DFS序,所以他的子节点的范围一定包含在他的左右位置中。
所以就变成了很明显的线段树成段更新...
注意一点的是,查询是单点更新...
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int MAXN = 1e5 + 5; const int INF = 1e9 + 7; struct segtree { int l , r , val , lazy; }T[MAXN << 2]; struct data { int next , to; }edge[MAXN]; int head[MAXN] , cont , L[MAXN] , R[MAXN]; //链式前向星 inline void add(int u , int v) { edge[cont].to = v; edge[cont].next = head[u]; head[u] = cont++; } //DFS序 void dfs(int u) { L[u] = min(L[u] , ++cont); R[u] = max(R[u] , cont); for(int i = head[u] ; ~i ; i = edge[i].next) { int v = edge[i].to; dfs(v); } L[u] = min(L[u] , ++cont); R[u] = max(R[u] , cont); } void init(int p , int l , int r) { int mid = (l + r) >> 1; T[p].l = l , T[p].r = r , T[p].lazy = 0; if(l == r) { T[p].val = -1; return ; } init(p << 1 , l , mid); init((p << 1)|1 , mid + 1 , r); } void updata(int p , int l , int r , int val) { int mid = (T[p].l + T[p].r) >> 1; if(l == T[p].l && T[p].r == r) { T[p].val = val; T[p].lazy = val; return ; } if(T[p].lazy) { T[p << 1].val = T[(p << 1)|1].val = T[p << 1].lazy = T[(p << 1)|1].lazy = T[p].lazy; T[p].lazy = 0; } if(r <= mid) { updata(p << 1 , l , r , val); } else if(l > mid) { updata((p << 1)|1 , l , r , val); } else { updata(p << 1 , l , mid , val); updata((p << 1)|1 , mid + 1 , r , val); } } int query(int p , int index) { int mid = (T[p].l + T[p].r) >> 1; if(index == T[p].l && T[p].r == index) { return T[p].val; } if(T[p].lazy) { T[p << 1].val = T[(p << 1)|1].val = T[p << 1].lazy = T[(p << 1)|1].lazy = T[p].lazy; T[p].lazy = 0; } if(index <= mid) { return query(p << 1 , index); } else { return query((p << 1)|1 , index); } } int main() { int t , n , u , v , root , q; char str[5]; scanf("%d" , &t); for(int ca = 1 ; ca <= t ; ca++) { scanf("%d" , &n); cont = 0 , root = (n + 1) * n / 2; for(int i = 1 ; i <= n ; i++) { R[i] = head[i] = -1; L[i] = INF; } for(int i = 1 ; i < n ; i++) { scanf("%d %d" , &u , &v); root -= u; add(v , u); } cont = 0; dfs(root); init(1 , 1 , cont); printf("Case #%d:\n" , ca); scanf("%d" , &q); while(q--) { scanf("%s" , str); if(str[0] == 'T') { scanf("%d %d" , &u , &v); updata(1 , L[u] , R[u] , v); } else { scanf("%d" , &u); printf("%d\n" , query(1 , L[u])); } } } }
相关文章推荐
- 下拉导航栏消失,上拉导航栏出现的问题
- 分页:总页数算法小结
- LeetCode *** 100. Same Tree
- java io 读书笔记
- lintcode: Permutations II
- C语言基本数据类型(二)
- 1110. Complete Binary Tree (25) 完全二叉树、树的遍历
- jquery.validate.js表单验证
- zoj 1029 moving tables
- js将类数组转成数组
- 定高条块:.bar
- 软考中高项学员:2016年4月4日作业
- 二叉树的java实现和遍历
- 互联网时代下,做营销更多是要学会讲故事
- git log简介
- struts2工作原理
- 奇点视觉
- WKE——Webkit精简的纯C接口的浏览器
- iframe高度自适应
- grunt、Browsersync服务及weinre远程调试