• Spoj 2798 Qtree3


    一棵结点为黑色或白色的树,初始都是白色的。有两种操作 

    1 将一个结点换颜色
    2 询问从根到结点u路径上面的第一个黑色点,没有则输出-1
    Input
    In the first line there are two integers N and Q.
    In the next N-1 lines describe the edges in the tree: a line with two integers a b denotes an edge
    between a and b. The next Q lines contain instructions "0 i" or "1 v" (1 ≤ i, v ≤ N).
    Output
    For each "1 v" operation, write one integer representing its result.
    Sample Input
    9 8
    1 2
    1 3
    2 4
    2 9
    5 9
    7 9
    8 9
    6 8
    1 3
    0 8
    1 6
    1 7
    0 2
    1 9
    0 2
    1 9
    Sample Output
    -1
    8
    -1
    2
    -1

    #include<cstdio>
    #include<algorithm>
    #include<cstring> 
    using namespace std;const int N=200001;
    int n,m,sum,cnt,now,pre[N],f[N],nxt[N],h[N],top[N],id[N],size[N],dep[N],ans,maxx,di[N];
    struct oo{int a,b,dp,now;bool v;}s[N*2-20000];
    void dfs(int x)
    {
        size[x]=1;
        for(int i=h[x];i;i=nxt[i])
        {
            if(pre[i]==f[x])continue;
            dep[pre[i]]=dep[x]+1;
            f[pre[i]]=x;
            dfs(pre[i]);
            size[x]+=size[pre[i]];
        }
    }
    void dfs2(int x,int f)
    {
        int k=0;
        id[x]=++cnt;
        di[cnt]=x; //dfs序中第cnt个点是x 
        top[x]=f;
        for(int i=h[x];i;i=nxt[i])
            if(size[pre[i]]>size[k]&&dep[pre[i]]>dep[x])k=pre[i];
        if(!k)return ;
        dfs2(k,f);
        for(int i=h[x];i;i=nxt[i])
            if(dep[pre[i]]>dep[x]&&pre[i]!=k)
                dfs2(pre[i],pre[i]);
    }
    void ins(int x,int y)
    {
        pre[++now]=y;
        nxt[now]=h[x];
        h[x]=now;
    }
    void build(int x,int l,int r)
    {
        s[x].a=l,s[x].b=r;
    	s[x].dp=1e9;
        if(l==r)
    	 {
    			return ;
    	 }
        build(x<<1,l,l+r>>1);
        build(x<<1|1,(l+r>>1)+1,r);
    }
    void get(int x,int l,int r)
    //求出线段树上[l,r]哪个点是黑色的,且深度最小 
    {
        if(s[x].a>=l&&r>=s[x].b)
        {
            if(s[x].dp<maxx)
            {
                maxx=s[x].dp; //找出深度最小值 
                sum=s[x].now;//对应的点 
            }
            return ;
        }
        else
        {
            int mid=s[x].a+s[x].b>>1;
            if(l<=mid)get(x<<1,l,r);
            if(r>mid)get(x<<1|1,l,r);
        }
    }
    void qmax(int x,int y)
    {
        maxx=1e9,sum=-1;
        while(top[x]!=top[y])
        {
            if(dep[top[x]]<dep[top[y]])
    		   swap(x,y);
            get(1,id[top[x]],id[x]);
            x=f[top[x]];
        }
        if(id[x]>id[y])
    	    swap(x,y);
        get(1,id[x],id[y]);
        if(sum==0)
    	   sum=-1;
    }
    void change(int x,int l)
    //x指目前在哪个树上
    //l是指线段中哪个位置 
    {
        if(s[x].a==s[x].b)
        {
            s[x].v^=1;
            if(s[x].v) //如果染成黑色 
            {
                s[x].dp=dep[di[l]]; //求出深度 
                s[x].now=di[l];  
    			//di[l]指dfs序列中第l个点是原树上哪个点 
            }
            else  //还原成白色 
    		     s[x].dp=1e9,s[x].now=0;
            return ;
        }
        int mid=s[x].a+s[x].b>>1;
        if(l<=mid)
    	   change(x<<1,l);
        else 
    	    change(x<<1|1,l);
        if(s[x<<1].dp<s[x<<1|1].dp)//求出最小的深度 
        {
            s[x].dp=s[x<<1].dp;
            s[x].now=s[x<<1].now;
        }
        else
        {
            s[x].dp=s[x<<1|1].dp;
            s[x].now=s[x<<1|1].now;
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1,x,y;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            ins(x,y);
    		ins(y,x);
        }
        dfs(1);
    	dfs2(1,1); 
        build(1,1,n);
        int c;
        for(int i=1;i<=m;i++)
        {
            int a,b;
            scanf("%d",&c);
            if(c) //查询操作 
            {
                scanf("%d",&b);
                qmax(1,b);
                printf("%d
    ",sum);
            }
            if(!c) //将某个结点换颜色 
    		   scanf("%d",&b),change(1,id[b]);
        }
    }
    

      

     

      

  • 相关阅读:
    SpringBoot多数据源动态切换数据源
    @ConfigurationProperties 在IDEA中出现红色波浪线问题
    springboot+mybatis实现动态切换数据源
    Spring Boot配置多个DataSource
    模拟测试 20190714
    暴力日记
    模拟测试20190707 [排序//划艇//放棋子]
    组合数学总结
    莫比乌斯专题总结
    AC自动机总结
  • 原文地址:https://www.cnblogs.com/cutemush/p/11857851.html
Copyright © 2020-2023  润新知