HDU 3974
题意:公司里有员工,员工的上司,员工上司的上司...给一个人分配工作,他的直接员工和间接员工都会停下手中的工作一起去做的他的工作,问指定的一个人现在在做的工作。
dfs时间戳处理出每一个人对应的工作时间范围,类比成某个人管辖的区间。dfs序已经将每个人编号,所以区间的最左侧即为这个人自己。然后就将区间映射到线段树上,更新操作即为更新一个人对应的管辖区间,查询则是查询区间最左侧。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
using namespace std;
const int maxn = 2e5 + 10;
struct Tree{
int l, r;
int tag;
}t[maxn];
vector<int> g[maxn];
bool vis[maxn];
int L[maxn], R[maxn];
int tot;
void dfs(int u) {
L[u] = ++tot;
for (int i = 0; i < g[u].size(); i++){
dfs(g[u][i]);
}
R[u] = tot;
}
void build(int l, int r, int root)
{
t[root].l = l, t[root].r = r;
t[root].tag = -1;
if(l != r){
int mid = (l + r) >> 1;
build(l, mid, root << 1);
build(mid + 1, r, root << 1 | 1);
}
}
void push_down(int root)
{
t[root << 1].tag = t[root].tag;
t[root << 1 | 1].tag = t[root].tag;
t[root].tag = 0;
}
void update(int l, int r, int x, int root)
{
if(l <= t[root].l && t[root].r <= r){
t[root].tag = x;
return;
}
else{
if(t[root].tag != 0) push_down(root);
int mid = (t[root].l + t[root].r) >> 1;
if(r <= mid) update(l, r, x, root << 1);
else if(l > mid) update(l, r, x, root << 1 | 1);
else{
update(l, r, x, root << 1);
update(l, r, x, root << 1 | 1);
}
}
}
int query(int q, int root)
{
if(t[root].l == t[root].r) return t[root].tag;
else{
if(t[root].tag != 0) push_down(root);
int mid = (t[root].l + t[root].r) >> 1;
if(q <= mid) return query(q, root << 1);
else return query(q, root << 1 | 1);
}
}
int main()
{
int cas; scanf("%d", &cas);
for(int t = 0; t < cas; t++)
{
printf("Case #%d:\n", t+1);
int n; scanf("%d", &n); tot = 0;
for(int i = 0; i <= n; i++) g[i].clear();
memset(vis, false, sizeof(vis));
for(int i = 1; i < n; i++){
int x, y; scanf("%d%d", &x, &y);
vis[x] = true;
g[y].push_back(x);
}
for(int i = 1; i <= n; i++){
if(!vis[i]){
dfs(i);
break;
}
}
build(1, n, 1);
int m; scanf("%d", &m);
for(int i = 0; i < m; i++){
char ch; scanf(" %c", &ch);
if(ch == 'C'){
int qu; scanf("%d", &qu);
printf("%d\n", query(L[qu], 1));
}
else{
int qu, numb; scanf("%d%d", &qu, &numb);
update(L[qu], R[qu], numb, 1);
}
}
}
return 0;
}