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员工,当一个人 ...
随机推荐
- 大数据学习——mapreduce汇总手机号上行流量下行流量总流量
时间戳 手机号 MAC地址 ip 域名 上行流量包个数 下行 上行流量 下行流量 http状态码 1363157995052 13826544101 5C-0E-8B-C7-F1-E0:CMCC 12 ...
- 调用hcm接口同步员工数据更新员工信息没有同步到bdm
原来是更新的时候,baseEmployeeEntity的id为空,这时候需要把原先的baseEmployeeEntity1的id赋值给baseEmployeeEntity,问题解决
- 【ITOO 3】.NET 动态建库建表:实用EF框架提供的codeFirst实现动态建库
导读:在上篇博客中,介绍了使用SQL字符拼接的方式,实现动态建库建表的方法.这样做虽然也能够实现效果,但是,太麻烦,而且,如果改动表结构,字段的话,会对代码修改很多.但是EF给我们提供了一种代码先行的 ...
- CodeForces 20 A+B
A - BerOS file system 水题不解释了,压缩斜杆.要注意最后没有斜杠. char a[105]; ...
- 【Kubernetes】Kubernetes的Service外部访问方式:NodePort和LoadBalancer
Kubernetes的Pod的寿命是有限的,它们不会复活,因此尽管每个Pod都有自己的IP地址,但是这些IP地址是不可靠的,会随着Pod的消亡而消失. 这就带来一个问题,如果一些Pod的集合(称之为b ...
- 【DFS+剪枝】Square
https://www.bnuoj.com/v3/contest_show.php?cid=9154#problem/J [题意] 给定n个木棍,问这些木棍能否围成一个正方形 [Accepted] # ...
- 最小生成树求法 Prim + Kruskal
prim算法的思路 和dijkstra是一样的 每次选取一个最近的点 然后去向新的节点扩张 注意这里的扩张 不再是 以前求最短路时候的到新的节点的最短距离 而是因为要生成一棵树 所以是要连一根最短的连 ...
- 【HDOJ6342】Expression in Memories(模拟)
题意: 给定一个由0123456789+* ?组成的表达式,其中?可以被改为任意其它字符,问修改问号后是否有方案使得表达式合法 len<=5e2,sumlen<=1e5 思路: #incl ...
- 通过k8s(Kubernetes)搭建jmeter的压测环境master-slave架构,实现弹性伸缩
在k8s上部署jmeter的mater和slave,根据压测需求动态增减master和slave节点数量,即可以完成压测任务,又可以是资源利用最大化 https://blog.kubernauts.i ...
- Meteor check
check方法用于检查参数或类型是否匹配模式. 安装check包 打开命令提示符窗口,并安装该软件包. C:\Users\Administrator\Desktop\meteorApp>mete ...