hdu3974(多叉树时间戳建模成线段树)
来源:互联网 发布:网络对战平台 编辑:程序博客网 时间:2024/05/18 17:59
/*translation:一个公司里面每个员工都有一个顶头上司,一旦给某个员工分配任务后,这个员工以及该员工的所有下属都在做该任务。有若干操作,分配给员工任务以及查询该员工正在执行的任务。solution:线段树,时间戳一般化很明显该公司的所有员工间的关系可以用一颗多叉树来表示。然后就是dfs给这棵树打上时间戳。根据新分配的id号码将其节点对应映射到线段树上面。这样分配任务就相当与更新一段连续的节点,查询任务相当与单点查询。note:#: 这道题WA的原因在于搞错了多叉树和线段树间的映射关系。要明白线段树的本质就是对一整段连续区间进行操作。所以这道题的关键就在于清楚怎么将对多叉树的操作转化成对一整段连续区间的操作。date:2016.11.28*/#include <iostream>#include <cstdio>#include <vector>using namespace std;const int maxn = 50000 + 5;vector<int> boss[maxn];vector<int> employee[maxn];int L[maxn*4], R[maxn*4];//节点在树上所对应的覆盖范围以及新分配的idint n, q, cnt;int s[maxn*4], e[maxn*4];int task[maxn*4];void init(){for(int i = 0; i <= n; i++){boss[i].clear();employee[i].clear();}}void dfs(int u){++cnt;L[u] = cnt;for(int i = 0; i < boss[u].size(); i++){int v = boss[u][i];dfs(v);}R[u] = cnt;}void build(int l, int r, int o){s[o] = l;e[o] = r;task[o] = -1;if(l != r){int m = (l + r) >> 1;build(l, m, o << 1);build(m + 1, r, o << 1 | 1);}}void push_down(int o, int num){if(task[o] != -1){task[o << 1] = task[o << 1 | 1] = task[o];task[o] = -1;}}int query(int x, int o){if(s[o] == x && e[o] == x)return task[o];push_down(o, e[o] - s[o] + 1);int m = (s[o] + e[o]) >> 1;if(x <= m)return query(x, o << 1);elsereturn query(x, o << 1 | 1);}void update(int t, int l, int r, int o){if(s[o] == l && e[o] == r){task[o] = t;return;}if(s[o] == e[o])return;push_down(o, e[o] - s[o] + 1);int m = (s[o] + e[o]) >> 1;if(r <= m)update(t, l, r, o << 1);else if(l > m)update(t, l, r, o << 1 | 1);else{update(t, l, m, o << 1);update(t, m + 1, r, o << 1 | 1);}}int main(){//freopen("in.txt", "r", stdin);int T, kase = 0;scanf("%d", &T);while(T--){scanf("%d", &n);init();int u, v;for(int i = 1; i < n; i++){scanf("%d%d", &u, &v);boss[v].push_back(u);employee[u].push_back(v);}cnt = 0;for(int i = 1; i <= n; i++) if(employee[i].size() == 0){dfs(i);break;}build(1, cnt, 1);scanf("%d", &q);printf("Case #%d:\n", ++kase);char op[5];int x, y;while(q--){scanf("%s", op);if(op[0] == 'C'){scanf("%d", &x);printf("%d\n", query(L[x], 1));}else if(op[0] == 'T'){scanf("%d%d", &x, &y);//分配任务y给员工xupdate(y, L[x], R[x], 1);}}}return 0;}
0 0
- hdu3974(多叉树时间戳建模成线段树)
- 【HDU3974】【dfs时间戳建立区间】【线段树】
- hdu3974 线段树-2
- HDU3974 - Assign the task(线段树)
- 线段树之HDU3974 Assign the task
- hdu3974(dfs序建线段树)
- hdu3974 Assign the task(线段树/dfs)(好题)
- hdu3974 线段树 编号的处理 dfs 加 lazy思想
- HDU3974-Assign the task(线段树+区间建树)
- hdu 3974 Assign the task 线段树(时间戳)
- HDU 4366 Successor(线段树 DFS时间戳)
- 【ZOJ1610】【线段树】【建模】【注意端点和线段的区别】
- 时间序列线段树
- codeforces 750E New Year and Old Subsequence(线段树+矩阵建模)
- HDU 3794 Assign the task (时间戳dfs序线段树)
- [poj 3321]Apple Tree[模拟DFS][时间戳][线段树]
- 383C - Propagating tree 线段树加时间戳
- hdu 4107 Gangster(线段树,时间卡得很严)
- centos的自我学习
- .gitignore不生效
- 2016冬季练习
- LDD DMA访问内存
- windows无法格式化U盘
- hdu3974(多叉树时间戳建模成线段树)
- ASSM与三级位图结构
- 根据哈夫曼编码写数据压缩解压软件(java实现)
- 数据结构之——KMP算法
- Android ImageView 正确使用姿势
- POJ 3904 HDU 5072 容斥原理
- 师哥带着代码走查总结
- 数据结构与算法之——八大排序算法
- 怎么能防止网站被注入eval(base64_decode这种类型的木马?