hdu 3974 Assign the task(线段树+将树映射到区间)

来源:互联网 发布:比特币挖矿用什么软件 编辑:程序博客网 时间:2024/05/19 07:28

Assign the task

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=3974

解题思路:

题目大意:

一家公司有n个人,编号1~n,每个人都有一个直属上司。 

给你两种操作: 

1:给x分配任务y,此时,x会将y也分配给他的下属,下属再分配给下属……也就是x下面的人都会放下原先的任务(如果有)而去

做任务y。

2:询问x当前的任务,若没有则输出-1。

算法思想:

将树映射到区间的线段树。。。

主要是将原有的关系树根据BOSS关系从新编号,

以便把每个BOSS所带领的员工全部压入一个连续区间内,

然后记录每个BOSS的起始编号和他的最后一名的员工的编号,

然后用线段树成端更新,单点查找即可。

AC代码:

#include <bits/stdc++.h>using namespace std;const int maxn = 50005;int fa[maxn],cnt;int sta[maxn],tail[maxn],num[maxn],curTask[maxn];vector<int> g[maxn];struct node{    int l,r,setv;}tree[maxn<<2];void dfs(int u,int fa){    num[u] = ++cnt;    curTask[u] = num[u];    sta[u] = cnt;//BOSS的起始编号    int len = g[u].size();    for(int i = 0; i < len; ++i){        if(g[u][i] == fa)            continue;        dfs(g[u][i],u);    }    tail[u] = cnt;//该BOSS的最后一名员工的编号}void pushdown(int id){    if(tree[id].setv != -1){        tree[id<<1].setv = tree[id<<1|1].setv = tree[id].setv;        tree[id].setv = -1;    }}void build(int id,int l,int r){    tree[id].l = l;    tree[id].r = r;    tree[id].setv = -1;    if(l == r){        return;    }    int mid = (l+r)>>1;    build(id<<1,l,mid);    build(id<<1|1,mid+1,r);}void update(int id,int l,int r,int val){    if(tree[id].l >= l && tree[id].r <= r){        tree[id].setv = val;        return;    }    int mid = (tree[id].l+tree[id].r)>>1;    pushdown(id);    if(l <= mid)        update(id<<1,l,r,val);    if(r > mid)        update(id<<1|1,l,r,val);}int query(int id,int pos){    if(tree[id].l == tree[id].r)        return tree[id].setv;    int mid = (tree[id].l+tree[id].r)>>1;    pushdown(id);    if(pos <= mid)        return query(id<<1,pos);    else        return query(id<<1|1,pos);}int main(){    int T,t = 1;    scanf("%d",&T);    while(T--){        printf("Case #%d:\n",t++);        int n,q;        scanf("%d",&n);        for(int i = 0; i <= n; ++i)            g[i].clear();        memset(fa,0,sizeof(fa));        for(int i=1; i<n; ++i){            int u,v;            scanf("%d%d",&u,&v);            fa[u] = v;            g[u].push_back(v);            g[v].push_back(u);        }        cnt = 0;        for(int i=1; i<=n; ++i){            if(fa[i] == 0){                dfs(i,0);                break;            }        }        build(1,1,n);        scanf("%d",&q);        while(q--){            char op[5];            scanf("%s",op);            int x,y;            scanf("%d",&x);            if(op[0]=='C'){                printf("%d\n",query(1,curTask[x]));            }            else{                scanf("%d",&y);                update(1,sta[x],tail[x],y);            }        }    }    return 0;}


0 0