hdu3974----Assign the task

Assign the task

Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 780    Accepted Submission(s): 392

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

Source

2011 Multi-University Training Contest 14 - Host by FZU

Recommend

先dfs改时间戳,那么子树区间就连在一起了,然后就是区间更新单点查询

/*************************************************************************
    > File Name: hdu3974.cpp
    > Author: ALex
    > Mail: [email protected]
    > Created Time: 2015年01月11日 星期日 20时50分13秒
 ************************************************************************/

#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 50110;

struct node
{
	int l, r;
	int add;
	int job;
}tree[N << 2];

vector <int> edge[N];

int s[N], e[N], cnt;
int deg[N];

void dfs (int u)
{
	int m = edge[u].size();
	s[u] = ++cnt;
	for (int i = 0; i < m; ++i)
	{
		int v = edge[u][i];
		dfs (v);
	}
	e[u] = cnt;
}

void pushdown (int p)
{
	if (tree[p].add != -1)
	{
		tree[p << 1].add = tree[p << 1 | 1].add = tree[p].add;
		tree[p << 1].job = tree[p << 1 | 1].job = tree[p].add;
		tree[p].add = -1;
	}
}

void build (int p, int l, int r)
{
	tree[p].l = l;
	tree[p].r = r;
	tree[p].add = -1;
	tree[p].job = -1;
	if (l == r)
	{
		return;
	}
	int mid = (l + r) >> 1;
	build (p << 1, l, mid);
	build (p << 1 | 1, mid + 1, r);
}

void update (int p, int l, int r, int val)
{
	if (l == tree[p].l && r == tree[p].r)
	{
		tree[p].job = val;
		tree[p].add = val;
		return;
	}
	pushdown (p);
	int mid = (tree[p].l + tree[p].r) >> 1;
	if (r <= mid)
	{
		update (p << 1, l, r, val);
	}
	else if (l > mid)
	{
		update (p << 1 | 1, l, r, val);
	}
	else
	{
		update (p << 1, l, mid, val);
		update (p << 1 | 1, mid + 1, r, val);
	}
}

int query (int p, int pos)
{
	if (tree[p].l == tree[p].r)
	{
		return tree[p].job;
	}
	pushdown (p);
	int mid = (tree[p].l + tree[p].r) >> 1;
	if (pos <= mid)
	{
		return query (p << 1, pos);
	}
	else
	{
		return query (p << 1 | 1, pos);
	}
}

int main()
{
	int t, n, m;
	int icase = 1;
	char op[10];
	int x, y;
	scanf("%d", &t);
	while (t--)
	{
		scanf("%d", &n);
		memset (deg, 0, sizeof(deg));
		for (int i = 0; i <= n; ++i)
		{
			edge[i].clear();
		}
		int u, v;
		for (int i = 1; i <= n - 1; ++i)
		{
			scanf("%d%d", &u, &v);
			edge[v].push_back(u);
			deg[u]++;
		}
		int root;
		for (int i = 1; i <= n; ++i)
		{
			if (!deg[i])
			{
				root = i;
				break;
			}
		}
		cnt = 0;
		dfs (root);
		build (1, 1, cnt);
		scanf("%d", &m);
		printf("Case #%d:\n", icase++);
		while (m--)
		{
			scanf("%s", op);
			if (op[0] == 'C')
			{
				scanf("%d", &x);
				printf("%d\n", query(1, s[x]));
			}
			else
			{
				scanf("%d%d", &x, &y);
				int l = s[x];
				int r = e[x];
				update (1, l, r, y);
			}
		}
	}
	return 0;
}
时间: 2025-01-07 09:42:48

hdu3974----Assign the task的相关文章

HDU3974 Assign the task(多叉树转换为线段+线段树区间染色)

题目大意:有n个人,给你他们的关系(老板和员工),没有直属上司的人就是整个公司的领导者,这意味着n个人形成一棵树(多叉树).当一个人被分配工作时他会让他的下属也做同样的工作(并且立即停止手头正在做的工作),题目会询问你其中某个人正在做的工作. 解题思路:其实从"一个人分配他的下属做一样的工作"这里就可以看出来了,这相当于让一块区间的人都做一样的事,就是线段树区间染色问题.但不能使用线段树,要先将多叉树铺展开,将节点映射到线段上.把每个人的管理区段找出来(把属于同一个人管的放一起,上司放

线段树+dfs序(Apple Tree )(Assign the task )

线段树+dfs序 给定一棵n个节点的树,m次查询,每次查询需要求出某个节点深度为h的所有子节点. 作为预处理,首先将树的所有节点按深度保存起来,每个深度的所有节点用一个线性结构保存,每个深度的节点相对顺序要和前序遍历一致. 然后从树的根节点进行dfs,对于每个节点记录两个信息,一个是dfs进入该节点的时间戳in[id],另一个是dfs离开该节点的时间戳out[id]. 最后对于每次查询,求节点v在深度h的所有子节点,只需将深度为h并且dfs进入时间戳在in[v]和out[v]之间的所有节点都求出

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

Assign the task Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=3974 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 l

HDU 3974 Assign the task(树 并查集)

题意  公司中有n个员工  除了boss  每个员工都有自己的上司  自己下属的下属也是自己的下属  当给一个员工分配任务时  这个员工会把任务也分配到自己的所有下属   每个员工都只做最后一个被分配的任务  对于每个C x  输出员工x正在做的任务  没有就输出-1 把员工的关系数建成类似并查集的结构  把每个直接分配任务的员工的任务和任务分配时间保存起来  查询时只要找这个员工所有父节点中最晚分配的任务 #include <bits/stdc++.h> using namespace st

J - Assign the task

J - Assign the task HDU - 3974 思路:一眼秒思路<(* ̄▽ ̄*)/ dfs序+线段树. 通过dfs序把树上问题转化成线段上的问题.然后用线段树解决. 错因:都是些zz的错误就不说了 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 50010 using namespace std; int t,n,

HDU 3974 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, an

HDU 3974 Assign the task(线段树)

描述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 subordin

HDU 3947 Assign the task

http://acm.hdu.edu.cn/showproblem.php?pid=3974 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

HDU 3974 Assign the task(dfs编号+线段树成段更新)

题意:给定点的上下级关系,规定如果给i分配任务a,那么他的所有下属.都停下手上的工作,开始做a. 操作 T x y 分配x任务y,C x询问x的当前任务: 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 思路: 利用dfs深度优先遍历重新编号,使一个结点的儿子连续.然后成段更新. 2:1-5 5:2-2 3:3-5 1:4-4 4:5-5 #include<iostr

HDU 3974 Assign the task(dfs时间戳+线段树成段更新)

题意:给定点的上下级关系,规定假设给i分配任务a.那么他的全部下属.都停下手上的工作,開始做a. 操作 T x y 分配x任务y,C x询问x的当前任务: 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 思路: 利用dfs深度优先遍历又一次编号.使一个结点的儿子连续. 然后成段更新. 代码: #include<iostream> #include<cstdio