zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    一些 好的链接
    图像滤波算法
    minigui中使用ttf字体库流程
    国庆长假归来
    vs2015 快捷键
    R11 u盘不能自动识别
    qt 自定义折线图
    qt QThread
    qt动态库编译和链接
    scons 库文件生成和链接
  • 原文地址:https://www.cnblogs.com/ljxdtc666/p/12230560.html
Copyright © 2011-2022 走看看