Assign the task

Problem Description
There is a company that has N employees(numbered from 1 to N),every employee in the company has a immediate boss (except for the leader of whole company).If you are the immediate boss of someone,that person is your subordinate, and all his subordinates are your subordinates as well. If you are nobody's boss, then you have no subordinates,the employee who has no immediate boss is the leader of whole company.So it means the N employees form a tree.

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.

 
Input
The 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)

 
Output
For 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
题目大意:一个工厂有n员工,员工之间有不同的下属关系,现在有n-1个关系将n个人构成一棵关系树,给某个人分配任务,这个人会将自己当前的任务分配给他的所有属下。给定m次操作,一种操作是询问x员工的当前任务,另一种操作是给x员工分配y任务。
思路:由于现在是一棵关系树,我们可以将按子节点的个数划分区间,对于某个节点,从根节点遍历到当前节点的num数为该节点的左区间,遍历完当前节点所有子节点之后的num为该节点的右区间,那么当前的区间就包含了当前节点的所有子节点。 我觉得难点就是在这里吧!根据树划分区间,之后的都是线段树的基本操作了
 
  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<cstdio>
  5.  
  6. using namespace std;
  7. const int maxn = ;
  8. struct node{
  9. int to,next;
  10. }e[maxn];
  11. int a[maxn<<],add[maxn<<];
  12. int f[maxn],head[maxn];
  13. int ls[maxn],rs[maxn];
  14. int n,m,T,cnt,num;
  15. void ade(int u,int v)//加边 便于dfs搜索
  16. {
  17. e[cnt].to = u;
  18. e[cnt].next = head[v];
  19. head[v] = cnt++;
  20. }
  21. int Find(int x){//并查集
  22. if(x!=f[x])
  23. f[x] = Find(f[x]);
  24. return f[x];
  25. }
  26. void dfs(int rt)//求出当前节点覆盖的区间左值和右值
  27. {
  28. int x = head[rt];
  29. ls[rt] = ++num;
  30. while(x!=-){
  31. dfs(e[x].to);
  32. x = e[x].next;
  33. }
  34. rs[rt] = num;
  35. }
  36. void pushdown(int rt)
  37. {
  38. if(add[rt]){
  39. a[rt<<] = a[rt];
  40. a[rt<<|] = a[rt];
  41. add[rt<<] = add[rt];
  42. add[rt<<|] = add[rt];
  43. add[rt] = ;
  44. }
  45. }
  46. void build(int l,int r,int rt)
  47. {
  48. a[rt] = -;//
  49. add[rt] = ;//此处初始化所有点线段树节点都为-1和0;
  50. if(l==r)return;
  51. int mid = (l+r)>>;
  52. build(l,mid,rt<<);
  53. build(mid+,r,rt<<|);
  54. }
  55. void update(int L,int R,int C,int l,int r,int rt)
  56. {
  57. if(L<=l&&r<=R){
  58. a[rt] = C;
  59. add[rt] = C;
  60. return;
  61. }
  62. pushdown(rt);//下推懒惰标记
  63. int mid = (l+r)>>;
  64. if(L<=mid)update(L,R,C,l,mid,rt<<);
  65. if(R>mid)update(L,R,C,mid+,r,rt<<|);
  66. }
  67. int query(int L,int R,int l,int r,int rt)
  68. {
  69. if(L<=l&&r<=R)return a[rt];
  70. pushdown(rt);//下推懒惰标记
  71. int mid = (l+r)>>;
  72. int ans = ;
  73. if(L<=mid) ans += query(L,R,l,mid,rt<<);
  74. if(R>mid) ans += query(L,R,mid+,r,rt<<|);
  75. return ans;
  76. }
  77. int main()
  78. {
  79. scanf("%d",&T);
  80. for(int t=;t<=T;t++){
  81. scanf("%d",&n);
  82. cnt = ,num = ;
  83. for(int i=;i<=n;i++){
  84. f[i]=i;head[i]=-;
  85. ls[i]=,rs[i]=;
  86. }
  87. for(int l,r,i=;i<n;i++){
  88. scanf("%d%d",&l,&r);
  89. f[l]=r;
  90. ade(l,r);
  91. }
  92. int root = Find();//利用并查集的思想求出根节点
  93. dfs(root);//根据根节点 求出每个节点覆盖的区间 区间左值在ls中,右值在rs中
  94. // cout<<ls[root]<<" "<<rs[root]<<endl;
  95. // for(int i=1;i<=n;i++)
  96. // cout<<ls[i]<<" "<<rs[i]<<endl;
  97. // getchar();
  98. build(,n,);
  99. scanf("%d",&m);
  100. char op;int x,y;
  101. printf("Case #%d:\n",t);
  102. while(m--){
  103. scanf(" %c",&op);
  104. if(op=='C'){
  105. scanf("%d",&x);
  106. printf("%d\n",query(ls[x],ls[x],,n,));//区间的单点查询
  107. }else if(op=='T'){
  108. scanf("%d%d",&x,&y);
  109. update(ls[x],rs[x],y,,n,);//区间更新当前的任务
  110. }
  111. }
  112. }
  113. return ;
  114. }

HDU 3974 Assign the task的更多相关文章

  1. HDU 3974 Assign the task 并查集/图论/线段树

    Assign the task Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?p ...

  2. HDU 3974 Assign the task 暴力/线段树

    题目链接: 题目 Assign the task Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...

  3. HDU 3974 Assign the task(简单线段树)

    Assign the task Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  4. HDU 3974 Assign the task (DFS序 + 线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3974 给你T组数据,n个节点,n-1对关系,右边的是左边的父节点,所有的值初始化为-1,然后给你q个操 ...

  5. 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 ...

  6. HDU 3974 Assign the task 并查集

    http://acm.hdu.edu.cn/showproblem.php?pid=3974 题目大意: 一个公司有N个员工,对于每个员工,如果他们有下属,那么他们下属的下属也是他的下属. 公司会给员 ...

  7. hdu 3974 Assign the task(线段树)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=3974 题意:给定一棵树,50000个节点,50000个操作,C x表示查询x节点的值,T x y表示更 ...

  8. hdu 3974 Assign the task (线段树+树的遍历)

    Description There is a company that has N employees(numbered from 1 to N),every employee in the comp ...

  9. hdu 3974 Assign the task(dfs序上线段树)

    Problem Description There is a company that has N employees(numbered from 1 to N),every employee in ...

随机推荐

  1. pl/sql基础知识—包

    n  包 包用于在逻辑上组合过程和函数,它由包规范和包体两部分组成. 为什么需要包:使用包可以更好的管理自己写的函数.过程 ①我们可以使用create package命令来创建包:     creat ...

  2. PLAY2.6-SCALA(三) 数据的返回与保存

    1.修改默认的Content-Type 自动设置内容类型为text/plain val textResult = Ok("Hello World!") 自动设置内容类型为appli ...

  3. IIS 设置 FTP 服务器 添加多个账户

    我们有很多童鞋经常开不动IIS自带的FTP如何创建,就算创建了也不会实现多用户,下面我来分享一下我的经验吧: 使用 IIS 设置 FTP 服务器 依次单击“开始”按钮.“控制面板”和“添加或删除程序” ...

  4. hdu5137 枚举删点

    #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; ; ; ...

  5. 生成主键ID,唯一键id,分布式ID生成器雪花算法代码实现

    工具类:  package com.ihrm.common.utils; import java.lang.management.ManagementFactory; import java.net. ...

  6. win10下Anaconda3配置环境变量

    有时候在win10安装好Anaconda3后,使用conda命令时依然会出现: C:\Users\dell\PycharmProjects\pytorch>conda list 'conda' ...

  7. Java中try catch finally语句中含return语句的执行情况总结-编程陷阱

    前言:有java编程基础的人对java的异常处理机制都会有一定了解,而且可能感觉使用起来也比较简单,但如果在try catch finally语句块中遇到return语句,开发者可能就会遇到一些逻辑问 ...

  8. spider csdn blog part II

    继续上次的笔记, 继续完善csdn博文的提取. 发现了非常好的模块. html2docx 结果展示: 运行之后, 直接生成docx文档. 截个图如下: 结果已经基本满意了!!! 在编写过程中的一些感想 ...

  9. 强制去除xcode的编译警告

    使用 #pragma clang diagnostic ignored 语法来强制去除xcode的编译警告,代码举例如下: #pragma clang diagnostic push #pragma ...

  10. WPF Canvas实现进度条

    原文:WPF Canvas实现进度条 先看效果图: 思路: 一个Canvas做背景,一个Canvas用来显示进度,图片放在显示进度的Canvas中,靠右设置为图片本身宽度一半的距离,视觉上实现以图片中 ...