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;
}

posted @ 2017-07-20 20:16  />.<\  阅读(170)  评论(0编辑  收藏  举报