Pagini recente » Cod sursa (job #2606317) | Rating me mydelf i (luminita) | Cod sursa (job #849340) | Cod sursa (job #77417) | Cod sursa (job #1221275)
#include <fstream>
#include <cstdlib>
using namespace std;
const int N = 2e5, B = 4, LG = 18 - B;
class FastLCA{
int rmq[LG][N >> B];
int *bro, *son, *depth, *euler, *S, *D, *poz;
inline int best(int x, int y){
return depth[x] < depth[y] ? x : y;
}
inline int best(int x, int y, int z, int t){
return best( best(x, y), best(z, t) );
}
void dfs(int x){
euler[ ++euler[0] ] = x;
poz[x] = euler[0];
for (int y = son[x] ; y ; y = bro[y]){
depth[y] = 1 + depth[x];
dfs(y);
euler[ ++euler[0] ] = x;
}
}
public:
void buildTree(int T[], int n){
poz = (int*)calloc(n + 1, sizeof(int));
depth = (int*)calloc(n + 1, sizeof(int));
euler = (int*)calloc(2 * n, sizeof(int));
S = bro = (int*)calloc(2 * n + 1, sizeof(int));
D = son = (int*)calloc(2 * n + 1, sizeof(int));
for (int i = 2 ; i <= n ; i++){
bro[i] = son[ T[i] ];
son[ T[i] ] = i;
}
dfs(1);
S[0] = D[0] = 0;
depth[0] = n;
int mask = (1 << B) - 1;
for (int i = euler[0] ; i ; i--)
if (i & mask)
S[i] = best(S[i + 1], euler[i]);
else
S[i] = euler[i];
for (int i = 1 ; i <= euler[0] ; i++)
if ( i & mask )
D[i] = best(D[i - 1], euler[i]);
else
D[i] = euler[i];
int size = euler[0] >> B;
for (int i = 0 ; i < size ; i++)
rmq[0][i] = D[ (i << B) ^ mask ];
rmq[0][size] = D[ euler[0] ];
for (int i = 1, step = 1 ; i < LG ; i++)
for (int j = 0 ; j <= size ; j++)
rmq[i][j] = best(rmq[i - 1][j], rmq[i - 1][j + step]);
}
inline int lca(int x, int y){
x = poz[x];
y = poz[y];
if (x > y)
swap(x, y);
if ( (x >> B) == (y >> B) ){
int ans = 0;
for (int i = x ; i <= y ; i++)
ans = best(ans, euler[i]);
return ans;
}
if ( (y >> B) == (x >> B) + 1 )
return best(S[x], D[y]);
int L = 31 - __builtin_clz( (y >> B) - (x >> B) - 1);
return best( S[x], rmq[L][1 + (x >> B)], rmq[L][(y >> B) - (1 << L)], D[y] );
}
};
FastLCA tree;
int T[N], n;
int main(){
ifstream in("lca.in");
ofstream out("lca.out");
int nrQ, x, y;
in >> n >> nrQ;
for (int i = 2 ; i <= n ; i++)
in >> T[i];
tree.buildTree(T, n);
while (nrQ--){
in >> x >> y;
out << tree.lca(x, y) << '\n';
}
out.close();
in.close();
return 0;
}