J - Assign the task

思路:一眼秒思路<(* ̄▽ ̄*)/
dfs序+线段树。
通过dfs序把树上问题转化成线段上的问题。然后用线段树解决。
 
 错因:都是些zz的错误就不说了
 
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 50010
using namespace std;
int t,n,m;
int sz,tot,sum,root;
int to[MAXN*2],net[MAXN*2],head[MAXN];
int dad[MAXN],idl[MAXN],idr[MAXN],edge[MAXN];
struct nond{
    int l,r,flag;
}tree[MAXN*4];
void add(int u,int v){
    to[++tot]=v;net[tot]=head[u];head[u]=tot;
}
void build(int now,int l,int r){
    tree[now].l=l;tree[now].r=r;
    tree[now].flag=-1;
    if(tree[now].l==tree[now].r)    return ;
    int mid=(tree[now].l+tree[now].r)/2;
    build(now*2,l,mid);
    build(now*2+1,mid+1,r);
}
void down(int now){
    tree[now*2].flag=tree[now*2+1].flag=tree[now].flag;
    tree[now].flag=-1;
    return ;
}
void change(int now,int l,int r,int pos){
    if(tree[now].l==l&&tree[now].r==r){
        tree[now].flag=pos;
        return ;
    }
    if(tree[now].flag!=-1)    down(now);
    int mid=(tree[now].l+tree[now].r)/2;
    if(r<=mid)    change(now*2,l,r,pos);
    else if(l>mid)    change(now*2+1,l,r,pos);
    else { change(now*2,l,mid,pos);change(now*2+1,mid+1,r,pos); }
}
int query(int now,int x){
    if(tree[now].l==tree[now].r)
        return tree[now].flag;
    if(tree[now].flag!=-1)    down(now);
    int mid=(tree[now].l+tree[now].r)/2;
    if(x<=mid)    return query(now*2,x);
    else return query(now*2+1,x);
}
void dfs(int now){
    idl[now]=++sz;
    for(int i=head[now];i;i=net[i])
        if(dad[now]!=to[i]){
            dad[to[i]]=now;
            dfs(to[i]);
        }
    idr[now]=++sz;
}
int main(){
    scanf("%d",&t);
    while(t--){
        sum++;printf("Case #%d:\n",sum);
        scanf("%d",&n);tot=0;
        for(int i=1;i<n;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            add(v,u);edge[u]++;
        }
        for(int i=1;i<=n;i++)
            if(edge[i]==0){ root=i;break; }
        dfs(root);build(1,1,sz);
        scanf("%d",&m);
        for(int i=1;i<=m;i++){
            char c;int x,y;
            scanf("\n%c%d",&c,&x);
            if(c=='T'){
                scanf("%d",&y);
                change(1,idl[x],idr[x],y);
            }
            else    printf("%d\n",query(1,idl[x]));
        }
        root=0;sz=0;
        memset(to,0,sizeof(to));
        memset(idl,0,sizeof(idl));
        memset(idr,0,sizeof(idr));
        memset(net,0,sizeof(net));
        memset(dad,0,sizeof(dad));
        memset(edge,0,sizeof(head));
        memset(head,0,sizeof(head));
    }
}
/*
1 
5 
4 3 
3 2 
1 3 
5 2 
5 
C 3 
T 2 1
 C 3 
T 3 2 
C 3
*/

 

posted @ 2018-02-25 19:07  一蓑烟雨任生平  阅读(163)  评论(0编辑  收藏  举报