Pagini recente » Cod sursa (job #1270415) | Cod sursa (job #305659) | Cod sursa (job #1180230) | Cod sursa (job #3159526) | Cod sursa (job #1932966)
#include <stdio.h>
#include <vector>
#define N 100005
#define log 18
using namespace std;
vector<int> g[N];
int n,m,i,j,a,b,q;
int lvl[N],euler[2*N],ap[N],rmq[log][2*N],log2[2*N]; ///rmq[j][i]=nodul cu lvl minim dintre nodurile din euler[k], k de la i la i+2^j
bool viz[N];
int min(int a,int b)
{
if(a<b)
return a;
return b;
}
void dfs(int x,int l)
{
int i;
viz[x]=true;
lvl[x]=l;
euler[++q]=x;
ap[x]=q;
for(i=0;i<g[x].size();i++)
if(!viz[g[x][i]])
{
dfs(g[x][i],l+1);
euler[++q]=x;
}
}
int query(int x,int y)
{
int p=log2[y-x+1];
return min(rmq[p][x],rmq[p][y-(1<<p)+1]);
}
int main()
{
FILE *f1,*f2;
f1=fopen("lca.in","r");
f2=fopen("lca.out","w");
fscanf(f1,"%d%d",&n,&m);
for(i=2;i<=n;i++)
{
fscanf(f1,"%d",&a);
g[i].push_back(a);
g[a].push_back(i);
}
dfs(1,0);
rmq[0][1]=euler[1];
for(i=2;i<=q;i++)
{
rmq[0][i]=euler[i];
log2[i]=log2[i/2]+1;
}
for(j=1;(1<<j)<=q;j++)
for(i=1;i<=q;i++)
{
if(lvl[rmq[j-1][i]]<lvl[rmq[j-1][i+(1<<(j-1))]])
rmq[j][i]=rmq[j-1][i];
else
rmq[j][i]=rmq[j-1][i+(1<<(j-1))];
}
while(m--)
{
fscanf(f1,"%d%d",&a,&b);
if(ap[a]>ap[b])
swap(a,b);
fprintf(f2,"%d\n",query(ap[a],ap[b]));
}
/*for(j=0;(1<<j)<=q;j++)
{
for(i=1;i<=q;i++)
printf("%d ",lvl[rmq[j][i]]);
printf("\n");
}*/
return 0;
}