J - Assign the task - hdu 3974(DFS建树+简单线段树)

题意:给一些节点简单额对应关系,可以组成一个树,如果树的某一个节点更新那么他的所有子节点都要更新,中间,会有一些查询
分析:题意倒也不难理解,但是但是不知道怎么建树。。。于是自能百度,看了kuangbin大神的博客豁然开朗,可以用每个节点的所包含的子节点段来当做线段树的节点,查找每个节点所包含的段可以用简单的DFS实现。
*************************************************************************
#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;

const int MAXN = 50005;

int Start[MAXN], End[MAXN];//每个员工所有下属的开始和结束节点,包含本身
int index;//DFS用记录节点的编号
vector<int> G[MAXN];//保存边

void DFS(int k)
{
    Start[k] = ++index;
    for(int i=0,len=G[k].size(); i<len; i++)
        DFS(G[k][i]);
    End[k] = index;
}

struct SegmentTree
{
    int L, R, task;
    bool isCover;
    int Mid(){return (L+R)/2;}
}a[MAXN*4];

void BuildTree(int r, int L, int R)
{
    a[r].L = L, a[r].R = R;
    a[r].task = -1, a[r].isCover = false;

    if(L == R)return ;

    BuildTree(r<<1, L, a[r].Mid());
    BuildTree(r<<1|1, a[r].Mid()+1, R);
}
void Down(int r)
{
    if(a[r].L != a[r].R && a[r].isCover)
    {
        a[r<<1].isCover = a[r<<1|1].isCover = true;
        a[r<<1].task = a[r<<1|1].task = a[r].task;
        a[r].isCover = false;
    }
}
void Insert(int r, int L, int R, int task)
{
    Down(r);

    if(a[r].L == L && a[r].R == R)
    {
        a[r].isCover = true;
        a[r].task = task;
        return ;
    }

    if(R <= a[r].Mid())
        Insert(r<<1, L, R, task);
    else if(L > a[r].Mid())
        Insert(r<<1|1, L, R, task);
    else
    {
        Insert(r<<1, L, a[r].Mid(), task);
        Insert(r<<1|1, a[r].Mid()+1, R, task);
    }
}
int  Query(int r, int k)
{
    Down(r);

    if(a[r].L == a[r].R)
        return a[r].task;

    if(k <= a[r].Mid())
        return Query(r<<1, k);
    else
        return Query(r<<1|1, k);
}

int main()
{
    int T, t=1;

    scanf("%d", &T);

    while(T--)
    {
        int i, N, M, u, v; char s[10];

        scanf("%d", &N);

        for(i=1; i<=N; i++)
            G[i].clear();
        bool use[MAXN] = {0};
        for(i=1; i<N; i++)
        {
            scanf("%d%d",&u, &v);
            G[v].push_back(u);
            use[u] = true;
        }

        index = 0;
        for(i=1; i<=N; i++)if(!use[i]){
            DFS(i); break;}

        BuildTree(11, N);
        printf("Case #%d:\n", t++);

        scanf("%d", &M);

        while(M--)
        {
            scanf("%s", s);

            if(s[0] == 'C')
            {
                scanf("%d", &u);
                printf("%d\n", Query(1, Start[u]));
            }
            else
            {
                scanf("%d%d", &u, &v);
                Insert(1, Start[u], End[u], v);
            }
        }
    }

    return 0;
}
posted @ 2015-07-27 14:38  无忧望月  阅读(1333)  评论(0编辑  收藏  举报
levels of contents