Codeforces 343D Water Tree

题意:一棵树有N个节点,有三种操作(1)“1 v",表示将以点v为根节点的子树全部赋值为1,(2)"2 v",表示将点v以及点v的所有祖先节点全部赋值为0,(3)"3 v",表示查询点v的值。

将树型转线性之后,我用了两棵线段树去维护这两种操作,明显可知的是,点v的子树里有一个点进行了操作(2),并且点v进行操作(1)(如果有)的时间早于操作2,那么点v的值就为0,在线段树里维护好每个操作的时间就可以了。

//#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
using namespace std;

#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define MID(a,b) (a+((b-a)>>1))

const int N=500005;

struct Edge
{
    int v,pre;
    Edge(){}
    Edge(int v,int pre) :
        v(v),pre(pre) {}
}edge[N*3];

int n,m;
int head[N],nEdge;
int low[N],high[N],idx;

void edgeInit()
{
    nEdge=0;
    memset(head,-1,sizeof(head));
}
void addEdge(int u,int v)
{
    edge[nEdge]=Edge(v,head[u]);
    head[u]=nEdge++;
}

void dfs(int u,int pre)
{
    low[u]=++idx;
    for(int i=head[u];i!=-1;i=edge[i].pre)
    {
        int v=edge[i].v;
        if(v==pre) continue;
        dfs(v,u);
    }
    high[u]=idx;
}

struct Segtree
{
    int delay[N*4],mx[N*4];

    void fun(int ind,int valu){ mx[ind]=delay[ind]=valu; }
    void PushDown(int ind)
    {
        if(delay[ind])
        {
            fun(LL(ind),delay[ind]);
            fun(RR(ind),delay[ind]);
            delay[ind]=0;
        }
    }
    void PushUp(int ind)
    {
        mx[ind]=max(mx[LL(ind)],mx[RR(ind)]);
    }
    void build(int lft,int rht,int ind)
    {
        delay[ind]=0;
        if(lft!=rht)
        {
            int mid=MID(lft,rht);
            build(lft,mid,LL(ind));
            build(mid+1,rht,RR(ind));
        }
    }
    void updata(int st,int ed,int valu,int lft,int rht,int ind)
    {
        if(st<=lft&&rht<=ed) fun(ind,valu);
        else
        {
            PushDown(ind);
            int mid=MID(lft,rht);
            if(st<=mid) updata(st,ed,valu,lft,mid,LL(ind));
            if(ed> mid) updata(st,ed,valu,mid+1,rht,RR(ind));
            PushUp(ind);
        }
    }
    int query(int st,int ed,int lft,int rht,int ind)
    {
        if(st<=lft&&rht<=ed) return mx[ind];
        else
        {
            PushDown(ind);
            int mid=MID(lft,rht);
            int mx1=0,mx2=0;
            if(st<=mid) mx1=query(st,ed,lft,mid,LL(ind));
            if(ed> mid) mx2=query(st,ed,mid+1,rht,RR(ind));
            PushUp(ind);
            return max(mx1,mx2);
        }
    }
}seg1,seg2;

int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        edgeInit(); idx=0;
        for(int i=1;i<n;i++)
        {
            int a,b; scanf("%d%d",&a,&b);
            addEdge(a,b); addEdge(b,a);
        }

        dfs(1,-1);

        seg1.build(1,idx,1); seg2.build(1,idx,1);

        scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            int a,u; scanf("%d%d",&a,&u);
            if(a==1) seg1.updata(low[u],high[u],i,1,idx,1);
            else if(a==2) seg2.updata(low[u],low[u],i,1,idx,1);
            else
            {
                int tmp1=seg1.query(low[u],low[u],1,idx,1);
                int tmp2=seg2.query(low[u],high[u],1,idx,1);
                if(tmp1>tmp2) puts("1");
                else puts("0");
            }
        }
    }
	return 0;
}



你可能感兴趣的:(Codeforces 343D Water Tree)