From Tree to Graph lca disjoint-set

  The meaning of problems: given an answer to the current tree tree $ f [1] ^ f [2] ^ f [3] ^ .. ^ f [n] $ f [i] represents the point i of the tree removed Unicom The number of blocks   

  M has two operations each time point and then outputs an edge even answer the tree

 

topic

Solution: The answer is clearly the beginning of time to answer each point of their answers so you can deal with a good beginning

    If the two points connected together when it passes by the path of the point (not both inclusive) will answer a Save   

           But given the sometimes repeated updates can be transferred to his son every point edge he obviously how many sons could be the answer to reducing the number of times just on the match

    With disjoint-set point to maintain the home so each side can only be traversed once it is shared equally complexity of the complexity of the m

    When the game was lca card is written in tree section lca can actually pre-out violence all lca

#include<bits/stdc++.h>
using namespace std;
const int N=5e3+10;
int f[N],n,a,b,x[2],y[2],z[2],deg[N],ans,m;
int find1(int x){return f[x]==x?x:f[x]=find1(f[x]);}
int dep[N],fa[N],siz[N],pre[N],id[N],lca[N][N],pos,ncnt,head[N];
struct Edge{int to,nex;}edge[N<<1];
void add(int a,int b){edge[++pos]=(Edge){b,head[a]};head[a]=pos;}
void dfs(int x,int f)
{
    fa[x]=f;dep[x]=dep[f]+1;id[x]=++ncnt;pre[ncnt]=x;siz[x]=1;lca[x][x]=x;
    for(int i=head[x];i;i=edge[i].nex)
    {
        int v=edge[i].to;
        if(v==f)continue;
        dfs(v,x);siz[x]+=siz[v];
        for(int j=id[x];j<id[v];j++)
            for(int k=id[v];k<id[v]+siz[v];k++)
            lca[pre[j]][pre[k]]=lca[pre[k]][pre[j]]=x;
    }
}
void solve(int x,int y)
{
    x=find1(x);
    while(dep[x]>dep[y]+1)
    {
         ans^=deg[fa[x]];
         deg[fa[x]]--;
         ans^=deg[fa[x]];
         f[x]=fa[x];
         x=find1(fa[x]);
    }
}
void init()
{
    for(int i=0;i<=n;i++)f[i]=i,head[i]=0,deg[i]=0;
    ncnt=ans=pos=0;
}
int main()
{
    while(scanf("%d%d%d%d%d%d",&n,&m,&a,&b,&x[0],&y[0])!=EOF)
    {
        int u,v;
        init();
        for(int i=1;i<n;i++)scanf("%d%d",&u,&v),add(u,v),add(v,u),deg[u]++,deg[v]++;
        dfs(0,0);
        for(int i=0;i<n;i++)ans^=deg[i];
        z[0]=ans;
        for(int i=1;i<=m;i++)
        {
            x[1]=(a*x[0]+b*y[0]+z[0])%n;
            y[1]=(b*x[0]+a*y[0]+z[0])%n;
            solve(x[1],lca[x[1]][y[1]]);
            z[0]=ans;x[0]=x[1];y[0]=y[1];
        }
        printf("%d %d\n",x[1],y[1]);
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/bxd123/p/11618282.html