Assign the task-HDU3974 dfs序+线段树

Posted ljxdtc666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
}

以上是关于Assign the task-HDU3974 dfs序+线段树的主要内容,如果未能解决你的问题,请参考以下文章

HDU 3974 Assign the task(线段树)

HDU3974 Assign the task

HDU 3974 Assign the task

hdu 3974 Assign the task(线段树)

HDOJ 3974 Assign the task

hdu 3974 Assign the task 线段树 DFS序