hdu3974 Assign the task(线段树/dfs)(好题)
来源:互联网 发布:手机预算软件 编辑:程序博客网 时间:2024/05/18 11:46
题目链接:点击链接
题意:
给一棵n个点的树,点标号从1到n。有两种操作,操作1,将树上的某个点以及它的子孙都赋值为某个数;操作2,查询某个点的值。
思路:
做法一:
dfs。更新时,将目标节点更新就行,给节点记录一个时间戳。查询时,向上访问父亲节点,对比儿子节点和父亲节点的时间戳,如果父亲节点的时间戳晚于儿子节点,儿子的值等于父亲的值,反之亦然。
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 50005;int cnt, cnt_now, ans;int ord[maxn], fa[maxn], idx[maxn];void init(){ memset(ord, -1, sizeof(ord)); memset(idx, -1, sizeof(idx)); memset(fa, -1, sizeof(fa)); cnt = 0;}void dfs(int x){ if(fa[x]==-1){ if(ord[x] > cnt_now){ cnt_now = ord[x]; ans = idx[x]; } } else{ if(ord[x] < ord[fa[x]]){ ord[x] = ord[fa[x]]; idx[x] = idx[fa[x]]; } if(ord[x] > cnt_now){ cnt_now = ord[x]; ans = idx[x]; } dfs(fa[x]); }}int main(){ char opt[10]; int t, n, a, b, m, Case=0; scanf("%d", &t); while(t--){ init(); scanf("%d", &n); for(int i=0; i<n-1; ++i){ scanf("%d%d", &a, &b); fa[a] = b; } scanf("%d", &m); printf("Case #%d:\n", ++Case); for(int i=0; i<m; ++i){ scanf("%s", opt); if(opt[0] == 'C'){ scanf("%d", &a); cnt_now = -1; ans = -1; dfs(a); printf("%d\n", ans); } if(opt[0] == 'T'){ scanf("%d%d", &a, &b); ord[a] = ++cnt; idx[a] = b; } } } return 0;}
做法二:
用dfs序建线段树。思路相当于,把当前节点管理所有儿子节点,转换为当前节点对应一条包含所有儿子的线段,
如何转换呢?dfs的时候,访问到当前节点x后,给节点x一个在线段树中的下标cnt,即节点x在线段树中对应的起点,记录为L[x] =cnt,继续深入,重复之前的操作,cnt不断加1。dfs再次返回到x时,我们知道节点x所管理的儿子在线段树中的终点为cnt,记录为R[x] = cnt,那么x节点对应的线段在线段树中为[L[x], R[x]],这样就完成了树到线段树的映射。
之后就是对应的区间懒惰更新,单点查询。
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>using namespace std;const int maxn = 50005;int cnt;int L[maxn], R[maxn];int tree[maxn<<2];int lazy[maxn<<2];int pre[maxn];vector<int> edges[maxn];void init(int n){ cnt = 0; memset(pre, 0, sizeof(pre)); memset(tree, -1, sizeof(tree)); memset(lazy, -1, sizeof(tree)); for(int i=1; i<=n; ++i) edges[i].clear(); }void dfs(int rt){ L[rt] = ++cnt; for(int i=0; i<edges[rt].size(); ++i){ dfs(edges[rt][i]); } R[rt] = cnt;}void pushdown(int rt){ if(lazy[rt]!=-1){ tree[rt<<1] = tree[rt<<1|1] = tree[rt]; lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt]; lazy[rt] = -1; }}void update(int rt, int a, int b, int l, int r, int x){ if(a<=l && r<=b){ tree[rt] = lazy[rt] = x; } else{ pushdown(rt); int mid = (l+r)>>1; if(a<=mid) update(rt<<1, a, b, l, mid, x); if(mid<b) update(rt<<1|1, a, b, mid+1, r, x); }}int query(int rt, int idx, int l, int r){ if(l==r && l==idx){ return tree[rt]; } else{ int mid = (l+r)>>1; pushdown(rt); if(idx<=mid) return query(rt<<1, idx, l, mid); if(mid<idx) return query(rt<<1|1, idx, mid+1, r); }}int main(){ char opt[10]; int t, n, a, b, m, Case=0; scanf("%d", &t); while(t--){ scanf("%d", &n); init(n); for(int i=0; i<n-1; ++i){ scanf("%d%d", &a, &b); edges[b].push_back(a); ++pre[a]; } for(int i=1; i<=n; ++i){ if(pre[i]==0){ dfs(i); break; } } scanf("%d", &m); printf("Case #%d:\n", ++Case); for(int i=0; i<m; ++i){ scanf("%s", opt); if(opt[0] == 'C'){ scanf("%d", &a); printf("%d\n", query(1, L[a], 1, cnt)); } if(opt[0] == 'T'){ scanf("%d%d", &a, &b); update(1, L[a], R[a], 1, cnt, b); } } } return 0;}
阅读全文
0 0
- hdu3974 Assign the task(线段树/dfs)(好题)
- HDU3974 - Assign the task(线段树)
- 线段树之HDU3974 Assign the task
- HDU3974-Assign the task(线段树+区间建树)
- hdu3974 Assign the task
- hdu3974----Assign the task
- HDU3974-Assign the task
- HDU 3974 Assign the task (线段树+dfs序)
- HDU 3974 Assign the task(DFS建树+线段树)
- Assign the task(dfs+线段树_
- HDU Assign the task(dfs编号+线段树成段更新)
- Assign the task (线段树)
- HDU 3794 Assign the task (时间戳dfs序线段树)
- HDU-3974-Assign the task(线段树维护dfs序)
- HDU 3974 Assign the task(dfs序 + 线段树区间赋值,单点查询)
- hdoj 3974 Assign the task 【DFS + 线段树区间修改】
- J - Assign the task(dfs序+线段树)J
- HDU 3974 Assign the task (DFS + 线段树)
- VS10 C++ 引用第三方库总结
- PHP环境中GD库的开启方法
- Python 中的控制流
- MySQL问题系列---Access denied for user root'@'localhost
- Educational Codeforces Round 27 A—D 题解
- hdu3974 Assign the task(线段树/dfs)(好题)
- WEB服务器为什么取不到用户的MAC地址
- Hybris安装和各个Extention简单介绍
- 第二章 2.2归并排序
- MySQL下bin-log的三种模式(ROW、Statement、Mixed)
- python 使用eclipse编码运行出现SyntaxError: Non-UTF-8 code starting 解决方法
- hdu 6165 FFF at Valentine(传递闭包)
- Python基础入门1--基础语法
- Android模拟器打不开或者模拟器找不到