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
用dfs序来把这棵树化成线性的结构,然后线段树的单点修改和区间查询即可 用Start和End记录每个点所代表区间的起点和终点
#include <iostream> #include <cstdio> #include <sstream> #include <cstring> #include <map> #include <set> #include <vector> #include <stack> #include <queue> #include <algorithm> #include <cmath> #define MOD 2018 #define LL long long #define ULL unsigned long long #define Pair pair<int, int> #define mem(a, b) memset(a, b, sizeof(a)) #define _ ios_base::sync_with_stdio(0),cin.tie(0) //freopen("1.txt", "r", stdin); using namespace std; const int maxn = 100100, INF = 0x7fffffff; int head[maxn], Start[maxn], End[maxn], flag[maxn]; int a, b, x, y, ans, cnt, ret; struct node{ int l, r, w, f; }Node[maxn*4]; struct dot{ int v, next; }Dot[maxn]; void add(int u, int v) { Dot[ret].v = v; Dot[ret].next = head[u]; head[u] = ret++; } void dfs(int u) { ++cnt; Start[u] = cnt; for(int i=head[u]; i!=-1; i=Dot[i].next) dfs(Dot[i].v); End[u] = cnt; } void build(int k, int ll, int rr) { Node[k].l = ll, Node[k].r = rr; Node[k].w = -1; Node[k].f = 0; if(ll == rr) return; int m = (ll + rr) / 2; build(k*2, ll, m); build(k*2+1, m+1, rr); } void down(int k) { Node[k*2].f = Node[k].f; Node[k*2+1].f = Node[k].f; Node[k*2].w = Node[k].f; Node[k*2+1].w = Node[k].f; Node[k].f = 0; } void qp(int k) { if(Node[k].l == Node[k].r) { ans = Node[k].w; return; } if(Node[k].f) down(k); int m = (Node[k].l + Node[k].r) / 2; if(a <= m) qp(k*2); else qp(k*2+1); } void chinter(int k) { if(Node[k].l >= a && Node[k].r <= b) { Node[k].w = y; Node[k].f = y; return; } if(Node[k].f) down(k); int m = (Node[k].l + Node[k].r) / 2; if(a <= m) chinter(k*2); if(b > m) chinter(k*2+1); } int main() { int T, kase = 0; scanf("%d",&T); while(T--) { mem(head, -1); mem(flag, -1); mem(Start, -1); mem(End, -1); mem(Dot, 0); mem(flag, -1); ret = 0; cnt = 0; int n, m, se; printf("Case #%d: ",++kase); scanf("%d",&n); for(int i=1; i<n; i++) { int u, v; scanf("%d%d", &u, &v); flag[u] = v; se = v; add(v, u); } while(flag[se] != -1) se = flag[se]; dfs(se); build(1, 1, cnt); scanf("%d",&m); char str[3]; getchar(); for(int i=0; i<m; i++) { scanf("%s",str); if(strcmp(str, "C") == 0) { int p; ans = -1; scanf("%d",&p); a = Start[p]; qp(1); printf("%d ",ans); } else if(strcmp(str, "T") == 0) { scanf("%d%d", &x, &y); a = Start[x]; b = End[x]; chinter(1); } } } return 0; }