天天看點

Assign the task HDU - 3974

點選打開連結

利用dfs序将多叉樹映射到線段樹上

對于任意一個節點 在先序序列中每個子節點都在其後 而在後序序列中每個子節點都在其前 這樣就确定了多叉樹的一棵子樹線上段樹中的左右區間

#include <bits/stdc++.h>
using namespace std;

struct node1
{
    int l;
    int r;
    int laz;
    int val;
};

struct node2
{
    int l;
    int r;
};

struct node3
{
    int v;
    int next;
};

node1 tree[200010];
node2 point[50010];
node3 edge[50010];
int book[50010],first[50010];
int n,q,num;

void addedge(int u,int v)
{
    edge[num].v=v;
    edge[num].next=first[u];
    first[u]=num++;
    return;
}

void safari(int u,int fat)
{
    int i,v;
    point[u].l=num++;
    for(i=first[u];i!=-1;i=edge[i].next)
    {
        v=edge[i].v;
        if(v!=fat)
        {
            safari(v,u);
        }
    }
    point[u].r=num-1;
    return;
}

void pushdown(int cur)
{
    tree[cur*2].laz=tree[cur].laz;
    tree[cur*2].val=tree[cur].laz;
    tree[cur*2+1].laz=tree[cur].laz;
    tree[cur*2+1].val=tree[cur].laz;
    tree[cur].laz=-1;
    return;
}

void build(int l,int r,int cur)
{
    int m;
    tree[cur].l=l;
    tree[cur].r=r;
    tree[cur].laz=-1;
    tree[cur].val=-1;
    if(l==r) return;
    m=(l+r)/2;
    build(l,m,cur*2);
    build(m+1,r,cur*2+1);
    return;
}

int query(int tar,int cur)
{
    if(tree[cur].l==tree[cur].r)
    {
        return tree[cur].val;
    }
    if(tree[cur].laz>=0) pushdown(cur);
    if(tar<=tree[cur*2].r) return query(tar,cur*2);
    else return query(tar,cur*2+1);
}

void update(int ll,int rr,int val,int cur)
{
    if(ll<=tree[cur].l&&tree[cur].r<=rr)
    {
        tree[cur].laz=val;
        tree[cur].val=val;
        return;
    }
    if(tree[cur].laz>=0) pushdown(cur);
    if(ll<=tree[cur*2].r) update(ll,rr,val,cur*2);
    if(rr>=tree[cur*2+1].l) update(ll,rr,val,cur*2+1);
    return;
}

int main()
{
    int t,cas,i,u,v;
    char ch[2];
    scanf("%d",&t);
    for(cas=1;cas<=t;cas++)
    {
        scanf("%d",&n);
        memset(book,0,sizeof(book));
        memset(first,-1,sizeof(first));
        num=0;
        for(i=0;i<n-1;i++)
        {
            scanf("%d%d",&u,&v);
            book[u]=1;
            addedge(v,u);
        }
        num=1;
        for(i=1;i<=n;i++)
        {
            if(!book[i])
            {
                safari(i,-1);
                break;
            }
        }
        build(1,n,1);
        scanf("%d",&q);
        printf("Case #%d:\n",cas);
        while(q--)
        {
            scanf("%s",ch);
            if(ch[0]=='C')
            {
                scanf("%d",&u);
                printf("%d\n",query(point[u].l,1));
            }
            else
            {
                scanf("%d%d",&u,&v);
                update(point[u].l,point[u].r,v,1);
            }
        }
    }
    return 0;
}