Pagini recente » Cod sursa (job #1294103) | Cod sursa (job #1438386) | Cod sursa (job #2035653) | Cod sursa (job #2808022) | Cod sursa (job #371240)
Cod sursa(job #371240)
using namespace std;
#include<fstream>
#include<vector>
#define MAX_N 100002
#define lgMAX_N 20
int poz[MAX_N];
int euler[2*MAX_N+1], euler_len, M, N;
int rmq[lgMAX_N][2*MAX_N]; // rmq[i][j] = minimul din intervalul [i, i + 2^j-1]
int niv[MAX_N]; // niv[i] = adancimea nodului euler[i]
vector<int>G[MAX_N];
bool viz[MAX_N];
int lg[2*MAX_N];
void DFS(int x, int n)
{
if(viz[x]) return;
viz[x] = 1;
euler[++euler_len] = x;
niv[x] = n;
poz[x] = euler_len;
unsigned i;
for(i = 0; i < G[x].size(); ++i)
{
DFS(G[x][i], n+1);
euler[++euler_len] = x;
}
}
void RANGE()
{
int i,j;
for(i = 1; i <= euler_len; ++i)
rmq[0][i] = euler[i];
for(j = 1; (1<<j) <= euler_len; ++j)
for(i = 1; i + (1<<j) <= euler_len; ++i)
{
if( niv[rmq[j-1][i]] < niv[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))];
}
}
int LCA(int x, int y)
{
int i = min(poz[x], poz[y]), j = max(poz[x], poz[y]);
int k = lg[j-i+1];
if(niv[ rmq[k][i] ] < niv [ rmq[k][j-(1<<k)+1] ]) return rmq[k][i];
else return rmq[k][j-(1<<k)+1];
}
int main()
{
ifstream f("lca.in");
ofstream g("lca.out");
f>>N; f>>M;
int i,x,y;
for(i = 2; i <= 2*N; ++i)
lg[i] = lg[i/2] + 1;
for(i = 2; i <= N; ++i)
{
f>>x;
G[x].push_back(i);
}
DFS(1,1);
RANGE();
while(M--)
{
f>>x; f>>y;
g<<LCA(x,y)<<"\n";
}
return 0;
}