凭借记忆勉强写出的倍增LCA。

http://www.lydsy.com/JudgeOnline/problem.php?id=4281

/**************************************************************

    Problem: 4281

    User: 1349367067

    Language: C++

    Result: Accepted

    Time:6316 ms

    Memory:130180 kb

****************************************************************/

 

#include<iostream>

#include<cstdio>

#include<cstring>

#include<algorithm>

usingnamespacestd;

intn,m,k;

intfa[1000011]={};

intLCA[1000011][31]={},D;

intdepth[1000011]={};

intpre[31]={};

voidmake_LCA()

{

     D=0;

     intT=1;

     while(T<n) T*=2,D++;

     pre[0]=1;

     for(inti=1;i<=D;i++) pre[i]=pre[i-1]*2;

     for(inti=1;i<=n;i++)

         LCA[i][0]=fa[i];

     for(inti=1;i<=D;i++)

         for(intj=1;j<=n;j++)

         {

             if(LCA[j][i-1]==-1)

                LCA[j][i]=-1;

             else

                 LCA[j][i]=LCA[LCA[j][i-1]][i-1];

         }

}

voidfind_depth(intx)

{

     if(depth[x]!=0) return;

     if(depth[fa[x]]==0)

        find_depth(fa[x]);

     depth[x]=depth[fa[x]]+1;

     return;

}

intfind_LCA(intx,inty)

{

    if(depth[x]<depth[y]) swap(x,y);

    for(inti=D;i>=0;i--)

        if(depth[LCA[x][i]]>=depth[y])

           x=LCA[x][i];

    if(x==y) returnx;

    for(inti=D;i>=0;i--)

        if(LCA[x][i]!=LCA[y][i])

        {

           x=LCA[x][i];y=LCA[y][i];

        }

    returnfa[x];

}

voidinit()

{

     scanf("%d%d%d",&n,&m,&k);

     intl,r;

     fa[1]=-1;depth[1]=1;

     for(inti=1;i<n;i++)

     {

         scanf("%d%d",&l,&r);

         if(l>r) swap(l,r);

         fa[r]=l;

     }

     make_LCA();

     for(inti=1;i<=n;i++)

         find_depth(i);

}

intup_LCA(intx,intt)

{

    for(inti=D;i>=0;i--)

        if(t>=pre[i])

        {

           x=LCA[x][i];t-=pre[i];

        }

    returnx;

}

voidwork()

{

     intd,t,lca,len;

     for(inti=1;i<=k;i++)

     {

         scanf("%d%d",&d,&t);

         lca=find_LCA(m,d);

         len=depth[lca]*2-depth[m]-depth[d];

         len=-len;

         if(len<=t)

         {

            m=d;

            printf("%d ",m);

         }

         else

         {

             if((depth[m]-depth[lca])==t)

                m=lca;

             else

                 if((depth[m]-depth[lca])>t)

                    m=up_LCA(m,t);

                 else

                    m=up_LCA(d,len-t);

             printf("%d ",m);

         }

     }

}

intmain()

{

    init();

    work();

     

     

    return0;

}
View Code