Pagini recente » Cod sursa (job #2818557) | Cod sursa (job #2951200) | Cod sursa (job #317480) | Cod sursa (job #3038805) | Cod sursa (job #579289)
Cod sursa(job #579289)
#include<fstream>
#include<vector>
#define dmax 100010
using namespace std;
int n,m;
vector<int>a[dmax];
int elemeuler;
int euler[2*dmax],nivel[2*dmax],first[dmax];
int logaritm[2*dmax];
int rmq[20][2*dmax];
/*parcurgere euler*/
void parcurgere(int nod, int niv)
{
int i;
elemeuler++;
euler[elemeuler] = nod;
nivel[elemeuler] = niv;
if (first[nod] == 0)
first[nod] = elemeuler;
for (i=0; i<(int)a[nod].size(); i++)
{
parcurgere(a[nod][i], niv+1);
elemeuler++;
euler[elemeuler] = nod;
nivel[elemeuler] = niv;
}
}
/*calculez logaritmii*/
void calculare_log()
{
int i;
for (i=2; i<=elemeuler; i++)
logaritm[i] = logaritm[i/2] + 1;
}
/*calculez RMQ*/
void calculare_rmq()
{
int i,j;
for (i=1; i<=elemeuler; i++)
rmq[0][i] = i;
for (i=1; i<=logaritm[elemeuler]; i++)
for (j=1; j<=elemeuler-(1<<i)+1; j++)
if (nivel[rmq[i-1][j]] < nivel[rmq[i-1][j+(1<<(i-1))]])
rmq[i][j] = rmq[i-1][j]; else
rmq[i][j] = rmq[i-1][j+(1<<(i-1))];
}
/*calculez LCA*/
int rmqq(int x, int y)
{
int loga = logaritm[y-x+1];
if (nivel[rmq[loga][x]] < nivel[rmq[loga][y+1-(1<<loga)]])
return euler[rmq[loga][x]]; else
return euler[rmq[loga][y+1-(1<<loga)]];
}
/*ma pregatesc sa calculez LCA*/
int lca(int x, int y)
{
int xx,yy;
xx = first[x]; yy = first[y];
if (xx > yy)
swap(xx,yy);
return rmqq(xx,yy);
}
void citire()
{
int i,x,y;
ifstream fin("lca.in");
ofstream fout("lca.out");
fin>>n>>m;
for (i=2; i<=n; i++)
{
fin>>x;
a[x].push_back(i);
}
parcurgere(1,0);
calculare_log();
calculare_rmq();
for (i=1; i<=m; i++)
{
fin>>x>>y;
fout<<lca(x,y)<<'\n';
}
fin.close();
fout.close();
}
int main()
{
citire();
return 0;
}