Pagini recente » Cod sursa (job #2162540) | Cod sursa (job #1693200) | Cod sursa (job #1920913) | Cod sursa (job #2908194) | Cod sursa (job #3352556)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int NMAX=2e5;
struct LCT {
struct node {
int ch[2], parent, reversed;
};
node tree[NMAX+5];
int get(int x) {
if (x==tree[tree[x].parent].ch[0]) return 0;
if (x==tree[tree[x].parent].ch[1]) return 1;
return -1;
}
void push(int x){
if (tree[x].reversed) {
swap(tree[x].ch[0] , tree[x].ch[1]);
tree[tree[x].ch[0]].reversed ^= 1;
tree[tree[x].ch[1]].reversed ^= 1;
tree[x].reversed = 0;
}
}
void rotate(int x) {
int y = tree[x].parent, z=tree[y].parent;//y - parent, z - grandparent
int side=get(x);
if (get(y)!=-1) tree[z].ch[get(y)]=x;// move x under z
tree[x].parent=z;
tree[y].ch[side]=tree[x].ch[side^1];//move x child to y child
if (tree[y].ch[side]) tree[tree[y].ch[side]].parent=y;
tree[x].ch[side^1]=y;//move y under x
tree[y].parent=x;
}
void propagate(int x) {
if (get(x)!=-1) {
propagate(tree[x].parent);
}
push(x);
}
void splay(int x) {
propagate(x);
while (get(x)!=-1) {
int y=tree[x].parent;
if (get(y)!=-1) {
int side1=get(y), side2=get(x);
if (side1==side2) {
rotate(y);
}else {
rotate(x);
}
}
rotate(x);
}
}
int access(int x) {
int last_node=0;
while (x) {
splay(x);
tree[x].ch[1]=last_node;
last_node=x;
x=tree[x].parent;
}
return last_node;
}
int lca(int x, int y) {
access(x);
return access(y);
}
void make_root(int x) {
access(x);
splay(x);
tree[x].reversed ^= 1;
push(x);
}
int find_root(int x) {
access(x);
splay(x);
while (tree[x].ch[0]) {
push(x);
x=tree[x].ch[0];
}
splay(x);
return x;
}
void link(int x, int y) { // y parent x child
make_root(x);
if (find_root(y)!=x) {
tree[x].parent=y;
}
}
};
LCT lct;
int main() {
int n, m;
fin>>n>>m;
for (int i=2;i<=n;i++) {
int val;
fin>>val;
lct.link(val, i);
}
lct.make_root(1);
for (int i=1;i<=m;i++) {
int x, y;
fin>>x>>y;
fout<<lct.lca(x,y)<<'\n';
}
}