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为该节点的右区间,那么当前的区间就包含了当前节点的所有子节点。 我觉得难点就是在这里吧!根据树划分区间,之后的都是线段树的基本操作了
 
 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio> using namespace std;
const int maxn = ;
struct node{
int to,next;
}e[maxn];
int a[maxn<<],add[maxn<<];
int f[maxn],head[maxn];
int ls[maxn],rs[maxn];
int n,m,T,cnt,num;
void ade(int u,int v)//加边 便于dfs搜索
{
e[cnt].to = u;
e[cnt].next = head[v];
head[v] = cnt++;
}
int Find(int x){//并查集
if(x!=f[x])
f[x] = Find(f[x]);
return f[x];
}
void dfs(int rt)//求出当前节点覆盖的区间左值和右值
{
int x = head[rt];
ls[rt] = ++num;
while(x!=-){
dfs(e[x].to);
x = e[x].next;
}
rs[rt] = num;
}
void pushdown(int rt)
{
if(add[rt]){
a[rt<<] = a[rt];
a[rt<<|] = a[rt];
add[rt<<] = add[rt];
add[rt<<|] = add[rt];
add[rt] = ;
}
}
void build(int l,int r,int rt)
{
a[rt] = -;//
add[rt] = ;//此处初始化所有点线段树节点都为-1和0;
if(l==r)return;
int mid = (l+r)>>;
build(l,mid,rt<<);
build(mid+,r,rt<<|);
}
void update(int L,int R,int C,int l,int r,int rt)
{
if(L<=l&&r<=R){
a[rt] = C;
add[rt] = C;
return;
}
pushdown(rt);//下推懒惰标记
int mid = (l+r)>>;
if(L<=mid)update(L,R,C,l,mid,rt<<);
if(R>mid)update(L,R,C,mid+,r,rt<<|);
}
int query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)return a[rt];
pushdown(rt);//下推懒惰标记
int mid = (l+r)>>;
int ans = ;
if(L<=mid) ans += query(L,R,l,mid,rt<<);
if(R>mid) ans += query(L,R,mid+,r,rt<<|);
return ans;
}
int main()
{
scanf("%d",&T);
for(int t=;t<=T;t++){
scanf("%d",&n);
cnt = ,num = ;
for(int i=;i<=n;i++){
f[i]=i;head[i]=-;
ls[i]=,rs[i]=;
}
for(int l,r,i=;i<n;i++){
scanf("%d%d",&l,&r);
f[l]=r;
ade(l,r);
}
int root = Find();//利用并查集的思想求出根节点
dfs(root);//根据根节点 求出每个节点覆盖的区间 区间左值在ls中,右值在rs中
// cout<<ls[root]<<" "<<rs[root]<<endl;
// for(int i=1;i<=n;i++)
// cout<<ls[i]<<" "<<rs[i]<<endl;
// getchar();
build(,n,);
scanf("%d",&m);
char op;int x,y;
printf("Case #%d:\n",t);
while(m--){
scanf(" %c",&op);
if(op=='C'){
scanf("%d",&x);
printf("%d\n",query(ls[x],ls[x],,n,));//区间的单点查询
}else if(op=='T'){
scanf("%d%d",&x,&y);
update(ls[x],rs[x],y,,n,);//区间更新当前的任务
}
}
}
return ;
}

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. scroll 滚动到指定位置触发事件 and 点击一按钮/链接让页面定位在指定的位置

    scroll 滚动到指定位置触发事件:$(function(){ $(window).scroll(function() { var s =$(window).scrollTop(); if (s&g ...

  2. 七.Deque的应用案例-回文检查

    - 回文检测:设计程序,检测一个字符串是否为回文. - 回文:回文是一个字符串,读取首尾相同的字符,例如,radar toot madam. - 分析:该问题的解决方案将使用 deque 来存储字符串 ...

  3. Directx11教程(61) tessellation学习(3)

    原文:Directx11教程(61) tessellation学习(3)       现在我们看看在不同tess factor的情况下,三角形是如何细分的?(这儿三条边和内部tess factor值是 ...

  4. Directx11教程(45) alpha blend(2)

    原文:Directx11教程(45) alpha blend(2)     在myTutorialD3D11_40中,我们在场景中再添加一个box,并把box放在水里,实现半透明的效果.如下图所示: ...

  5. 1.Golang开山篇,GO就是NB!

    目录:GO就是NB GO sb吗 安装环境 GO就是NB,K2R三位大佬写的GO,学GO不吃亏! (1)我们为什么要学 高并发 深度 || 广度 (2)go学习思路和目标 多打多练 掌握go语言 做一 ...

  6. idea列编辑模式

    当我们想要选中一列时,在eclipse中alt+shit+a就可以选中一列了, 在网上很多的idea中列编辑的使用,但是对我的电脑却不管用,也不太清楚在哪里设置 最后无奈乱试一通,结果找到了 alt+ ...

  7. activemq入门demo

    创建maven工程,pom文件如下 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="ht ...

  8. React Native自定义导航栏

    之前我们学习了可触摸组件和页面导航的使用的使用: 从零学React Native之09可触摸组件 - 从零学React Native之03页面导航 - 经过之前的学习, 我们可以完成一个自定义导航栏了 ...

  9. 2018-8-10-WPF-轻量级-MVVM-框架入门-2.1.2

    title author date CreateTime categories WPF 轻量级 MVVM 框架入门 2.1.2 lindexi 2018-08-10 19:16:51 +0800 20 ...

  10. Redis源码解析:09redis数据库实现(键值对操作、键超时功能、键空间通知)

    本章对Redis服务器的数据库实现进行介绍,说明Redis数据库相关操作的实现,包括数据库中键值对的添加.删除.查看.更新等操作的实现:客户端切换数据库的实现:键超时相关功能的实现.键空间事件通知等. ...