HDU3974 Assign the task —— dfs时间戳 + 线段树
题目链接:https://vjudge.net/problem/HDU-3974
The company usually assigns some tasks to some employees to finish.When a task is assigned to someone,He/She will assigned it to all his/her subordinates.In other words,the person and all his/her subordinates received a task in the same time. Furthermore,whenever a employee received a task,he/she will stop the current task(if he/she has) and start the new one.
Write a program that will help in figuring out some employee’s current task after the company assign some tasks to some employee.
InputThe first line contains a single positive integer T( T <= 10 ), indicates the number of test cases.
For each test case:
The first line contains an integer N (N ≤ 50,000) , which is the number of the employees.
The following N - 1 lines each contain two integers u and v, which means the employee v is the immediate boss of employee u(1<=u,v<=N).
The next line contains an integer M (M ≤ 50,000).
The following M lines each contain a message which is either
"C x" which means an inquiry for the current task of employee x
or
"T x y"which means the company assign task y to employee x.
(1<=x<=N,0<=y<=10^9)OutputFor each test case, print the test case number (beginning with 1) in the first line and then for every inquiry, output the correspond answer per line.Sample Input
1
5
4 3
3 2
1 3
5 2
5
C 3
T 2 1
C 3
T 3 2
C 3
Sample Output
Case #1:
-1
1
2
题解:
1.可知:对一棵树进行dfs(前序遍历),并为每个结点分配一个时间戳,表明该结点是第几个被访问的结点。对于某一个结点(非叶子),它的所有子孙的遍历次序是紧跟着当前节点的。
2.根据时间戳dfn[u],把每个结点u映射到一维数组上。设le[u]为子树u开始访问的时间戳,可知le[u]=dfn[u];ri[u]为子树u结束访问的时间戳,可知ri[u]为结点u最后被访问的子孙的时间戳。所以结点u的作用域就是: [ le[u], ri[u] ]。因此,我们就可以用线段树的区间修改来进行维护了。
学习之处:
根据DFS的特性:对一棵树进行先序遍历,对于当前结点u,它的所有子孙的遍历次序是紧跟着当前节点的。
因此,我们可以根据时间戳,把一棵树映射到到一维数组上,且可以知道每棵子树的确切位置。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = 2e9;
const LL LNF = 2e18;
const int MAXN = 5e4+; vector<int>g[MAXN];
int have_fa[MAXN];
int index, dfn[MAXN], le[MAXN], ri[MAXN];
int task[MAXN<<]; void dfs(int u)
{
dfn[u] = le[u] = ++index;
for(int i = ; i<g[u].size(); i++)
dfs(g[u][i]);
ri[u] = index;
} void push_down(int u)
{
if(task[u]!=-)
{
task[u*] = task[u*+] = task[u];
task[u] = -;
}
} void set_val(int u, int l, int r, int x, int y, int val)
{
if(x<=l && r<=y)
{
task[u] = val;
return;
} push_down(u);
int mid = (l+r)>>;
if(x<=mid) set_val(u*, l, mid, x, y, val);
if(y>=mid+) set_val(u*+, mid+, r, x, y, val);
} int query(int u, int l, int r, int x)
{
if(l==r) return task[u]; push_down(u);
int mid = (l+r)>>;
if(x<=mid) return query(u*, l, mid, x);
else return query(u*+, mid+, r, x);
} int main()
{
int n, m, T;
scanf("%d", &T);
for(int kase = ; kase<=T; kase++)
{
scanf("%d", &n);
for(int i = ; i<=n; i++)
g[i].clear(), have_fa[i] = ;
for(int i = ; i<n; i++)
{
int u, v;
scanf("%d%d", &u, &v);
g[v].push_back(u);
have_fa[u] = ;
} index = ;
for(int i = ; i<=n; i++)
if(!have_fa[i])
dfs(i); scanf("%d", &m);
memset(task, -, sizeof(task));
printf("Case #%d:\n", kase);
for(int i = ; i<=m; i++)
{
char op[]; int x, y;
scanf("%s", op);
if(op[]=='T')
{
scanf("%d%d", &x, &y);
set_val(, , n, le[x], ri[x], y);
}
else
{
scanf("%d", &x);
printf("%d\n", query(, , n, dfn[x]));
}
}
}
}
HDU3974 Assign the task —— dfs时间戳 + 线段树的更多相关文章
- hdu3974 Assign the task dfs序+线段树
There is a company that has N employees(numbered from 1 to N),every employee in the company has a im ...
- HDU 3974 Assign the task(DFS序+线段树单点查询,区间修改)
描述There is a company that has N employees(numbered from 1 to N),every employee in the company has a ...
- [Assign the task][dfs序+线段树]
http://acm.hdu.edu.cn/showproblem.php?pid=3974 Assign the task Time Limit: 15000/5000 MS (Java/Other ...
- HDU 3974 Assign the task (DFS序 + 线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3974 给你T组数据,n个节点,n-1对关系,右边的是左边的父节点,所有的值初始化为-1,然后给你q个操 ...
- HDU 3974 Assign the task(dfs建树+线段树)
题目大意:公司里有一些员工及对应的上级,给出一些员工的关系,分配给某员工任务后,其和其所有下属都会进行这项任务.输入T表示分配新的任务, 输入C表示查询某员工的任务.本题的难度在于建树,一开始百思不得 ...
- HDU 3974 Assign the task(简单线段树)
Assign the task Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 5692 Snacks(dfs时间戳+线段树)
Snacks Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- hdu 3974 dfs时间戳+线段树
题意: 一个公司里面每个员工都有一个顶头上司,一旦给某个员工分配任务后,这个员工以及该员工的所有下属都在做该任务. 有若干操作,分配给员工任务以及查询该员工正在执行的任务. 题解: 典型的更新字树的操 ...
- Assign the task-HDU3974 dfs序+线段树
题意: 一个公司有n个员工,每个员工都有一个上司,一个人下属的下属也是这个人的下属,因此可将他们的关系看成一棵树, 然后给定两种操作,C操作是查询当前员工的工作,T操作是将y工作分配给x员工,当一个人 ...
随机推荐
- 【瞎扯】我的OI之路
这里大概是一些我自己对我的OI之路的一些记录. 2015.11不知道哪一天-- 我听说了"编程". 当时还不懂得啥是信息学竞赛,以为这只是纯粹的程序设计.后来才明白信息学竞赛是算法 ...
- intellij idea2016
注册server http://idea.imsxm.com
- 在C#代码中应用Log4Net系列教程(附源代码)地址
在博客园看到一篇关于Log4Net使用教程,比较详细,感谢这位热心的博主 博客园地址:http://www.cnblogs.com/kissazi2/archive/2013/10/29/339359 ...
- 【RMAN】RMAN跨版本恢复(下)--大版本异机恢复
[RMAN]RMAN跨版本恢复(下)--大版本异机恢复 BLOG文档结构图 ORACLE_SID=ORA1024G 关于10g的跨小版本恢复参考:http://blog.chinaunix.net/u ...
- ES6关于Promise的用法详解
Node的产生,大大推动了Javascript这门语言在服务端的发展,使得前端人员可以以很低的门槛转向后端开发. 当然,这并不代表迸发成了全栈.全栈的技能很集中,绝不仅仅是前端会写一些HTML和一些交 ...
- HDU 1102 Kruscal算法
题目大意:给定村庄的数量,和一个矩阵表示每个村庄到对应村庄的距离,矩阵主对角线上均为1 在给定一个数目Q,输入Q行之间已经有通道的a,b 计算还要至少修建多少长度的轨道 这道题目用Kruscal方法进 ...
- Maven查看依赖树
1.命令行,但是只能查看一层的引用 mvn dependency:tree 如图所示: 2.使用Eclipse的Dependency Hierarchy查看,这个就比较深层次的查看,如图所示: 3.使 ...
- dtrace-debug
https://www.objc.io/issues/19-debugging/dtrace/
- IOCP数据中间件
IOCP数据中间件 每包最大8K(8192字节),超过8187字节的数据要分包传输 首包有5个字节的包头:4字节数据长度(告诉对方,此次总共将传输几字节数据) + 1字节命令字(告诉对方,此次请求的何 ...
- javascript创建对象总结(javascript高级程序设计)
1.工厂模式 这样的模式抽象创建详细对象的过程.用函数封装特定的接口来创建类. function createStudent(name) { var o = new Object(); o.name ...