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员工,当一个人 ...
随机推荐
- tiles框架的definition讲解
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE tiles-definitions PUBL ...
- winfor应用程序打印报表清单
最近一周竟然有2位以前的同事问我在winfor应用程序里面打印怎么搞,所以才有了写这篇文章的打算,索性现在没事就写出来 在窗体上简单的布局设置一下如图 定义一个Model 我在里面放了属性之外还从写了 ...
- 【构造+DFS】2017多校训练三 HDU 6060 RXD and dividing
acm.hdu.edu.cn/showproblem.php?pid=6060 [题意] 给定一棵以1为根的树,把这颗树除1以外的结点划分为k个集合(可以有空集),把1加入划分后的集合 每个集合的结点 ...
- [Vijos] 天才的记忆
背景 神仙飞啊飞 描述 从前有个人名叫W and N and B,他有着天才般的记忆力,他珍藏了许多许多的宝藏.在他离世之后留给后人一个难题(专门考验记忆力的啊!),如果谁能轻松回答出这个问题,便可以 ...
- 关于Linux内核学习的一点点总结
关于Linux内核学习的一点点总结 关键词:Linux, 操作系统,内核 博客列表 由反汇编C程序来理解计算机是如何工作的 通过分析一个简化版时间片轮转多道程序内核代码来认识操作系统中的进程调度 通过 ...
- linux awk常用命令【转载】
简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再 ...
- nginx 安装过程中的not found
linux 发行版本:centos zlib not found openssl not found yum install zlib-devel yum install openssl-devel
- Construct Binary Tree from Preorder and Inorder Traversal (DFS,参考)
Given preorder and inorder traversal of a tree, construct the binary tree. Note:You may assume that ...
- java数据结构和算法09(哈希表)
树的结构说得差不多了,现在我们来说说一种数据结构叫做哈希表(hash table),哈希表有是干什么用的呢?我们知道树的操作的时间复杂度通常为O(logN),那有没有更快的数据结构?当然有,那就是哈希 ...
- IDEA添加作者注释
1.打开IDEA的settings,然后在Editor下找到File and Code Templates 2.然后选择File Header 选择需要注释的的格式即可.