Assign the task-HDU3974 dfs序+线段树

题意:

一个公司有n个员工,每个员工都有一个上司,一个人下属的下属也是这个人的下属,因此可将他们的关系看成一棵树,

然后给定两种操作,C操作是查询当前员工的工作,T操作是将y工作分配给x员工,当一个人得到y工作时,他的

员工也会得到这个工作,即这个点和他的子树的工作都变成y。

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

思路:

先一遍dfs求出该员工掌管的员工区间,每次修改时用线段树修改这个区间的员工即可,而查询时只要查询l_[x](该员工在dfs序下的编号)即可

代码:

#include <bits/stdc++.h>
#define ls node<<1,l,mid
#define rs node<<1|1,mid+1,r
using namespace std;
const int MAXN=5e4+4;
typedef long long ll;
int n;int l_[MAXN],r_[MAXN],f[MAXN];
int tree[MAXN<<2];
vector<int>v[MAXN];
int cnt;
void dfs(int now)
{
    l_[now]=++cnt;
    for(int i=0;i<v[now].size();i++)
    {
        dfs(v[now][i]);
    }
    r_[now]=cnt;
}
void build(int node,int l,int r)
{
    tree[node]=-1;
    if(l==r)
        return;
    int mid=(l+r)>>1;
    build(ls);
    build(rs);
}
void push_down(int node)
{
    if(tree[node]!=-1)//员工的任务等于上司的任务
    {
        tree[node<<1]=tree[node];
        tree[node<<1|1]=tree[node];
        tree[node]=-1;
    }
}
void update(int node,int l,int r,int x,int y,int k)
{
    if(x<=l&&y>=r)
    {
        tree[node]=k;
        return;
    }
    push_down(node);
    int mid=(l+r)>>1;
    if(x<=mid)
        update(ls,x,y,k);
    if(y>mid)
        update(rs,x,y,k);
}
int query(int node,int l,int r,int i)
{
    if(l==r)
    {
        return tree[node];
    }
    push_down(node);
    int mid=(l+r)>>1;
    if(i<=mid)
        return query(ls,i);
    else
        return query(rs,i);
}
void init()
{
    cnt=0;
    memset(f,0,sizeof(f));
    for(int i=1;i<=n;i++)
        v[i].clear();
}
int main()
{
    int t;scanf("%d",&t);int case_=0;
    while(t--)
    {
        printf("Case #%d:
",++case_);
        scanf("%d",&n);
        init(); //初始化
        for(int i=1;i<=n-1;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            v[y].push_back(x);
            f[x]=y;
        }
        for(int i=1;i<=n;i++)//获得dfs序
        {
            if(!f[i])
                dfs(i);
        }
        build(1,1,cnt);
        int q;scanf("%d",&q);
        while(q--)
        {
            char str[10];int x,y;
            scanf("%s",str);
            if(str[0]=='T')
            {
                scanf("%d%d",&x,&y);
                update(1,1,cnt,l_[x],r_[x],y);
            }
            else
            {
                scanf("%d",&x);
                printf("%d
",query(1,1,cnt,l_[x]));
            }
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/ljxdtc666/p/12230560.html