hiho1232 Couple Trees

来源:互联网 发布:unity3d ui界面素材 编辑:程序博客网 时间:2024/06/13 23:18
//倍增,二分,LCA,LCA是指树中两个点的最小公共祖先
//f[u][i]表示u节点的第2^i个父节点,倍增求,排好序,剔除重复部分
//求u和v的LCA时,如果u>v,那么先求u的父节点中大于等于v的第一个节点,付给u,如果u==v,退出,反之亦然
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define maxn 100002
int N,M;
int fa[maxn][20],ca[maxn],da[maxn];//da[i]表示从跟到i的距离,ca[i]表示i的父节点个数
int fb[maxn][20],cb[maxn],db[maxn];
void init()
{
    da[1]=db[1]=0;//根节点总是1
    fa[1][0]=fb[1][0]=1;//根节点的父节点总是自身
    int i,k;
    for(i=2;i<=N;i++)
    {
        scanf("%d",&fa[i][0]);
        da[i]=da[fa[i][0]]+1;
    }
    for(i=2;i<=N;i++)
    {
        scanf("%d",&fb[i][0]);
        db[i]=db[fb[i][0]]+1;
    }
    for(k=1;k<20;k++)
    {
        for(i=1;i<=N;i++)
        {
            //2^k-2^(k-1)=2^(k-1)
            fa[i][k]=fa[fa[i][k-1]][k-1];
            fb[i][k]=fb[fb[i][k-1]][k-1];
        }
    }
    for(i=1;i<=N;i++)
    {
        sort(fa[i],fa[i]+20);
        ca[i]=unique(fa[i],fa[i]+20)-fa[i];
        sort(fb[i],fb[i]+20);
        cb[i]=unique(fb[i],fb[i]+20)-fb[i];
    }
}
int solve(int u,int v)
{
    while(u!=v)
    {
        if(u>v)
        {
            int t=lower_bound(fa[u],fa[u]+ca[u],v)-fa[u];
            if(t==ca[u]) t--;
            u=fa[u][t];
        }
        else
        {
            int t=lower_bound(fb[v],fb[v]+ca[v],u)-fb[v];
            if(t==cb[v]) t--;
            v=fb[v][t];
        }
    }
    return u;
}
int main()
{
    while(scanf("%d %d",&N,&M)!=EOF)
    {
        init();
        int u,v,k=0;
        for(int i=1;i<=M;i++)
        {
            scanf("%d%d",&u,&v);
            u=(u+k)%N+1;
            v=(v+k)%N+1;
            k=solve(u,v);
            printf("%d %d %d\n",k,da[u]-da[k]+1,da[v]-da[k]+1);
        }
    }
}
0 0