Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- using ll = long long;
- int const nmax = 200000;
- int parent[1 + nmax];
- int fen[1 + nmax];
- int level[1 + nmax];
- inline int LSB(int x) {
- return x &-x;
- }
- inline int anc(int node, int k) {
- int r = level[node];
- int l = r - k;
- if (l < 1)return -1;
- while (l < r) {
- int nr = r - LSB(r);
- bool exceed = nr < l;
- node = exceed ? parent[node] : fen[node];
- r = exceed ? r - 1 : nr;
- }
- return node;
- }
- inline int lca(int a, int b) {
- if (level[a]>level[b]) {
- std::swap(a,b);
- }
- b=anc(b,level[b]-level[a]);
- int r=level[a];
- while(a!=b) {
- if (fen[a]==fen[b]){
- r--;
- a=parent[a];
- b=parent[b];
- } else {
- r-=r&-r;
- a=fen[a];
- b=fen[b];
- }
- }
- return a;
- }
- int main() {
- int n, q;
- std::cin >> n >> q;
- for(int i = 2; i <= n; i++)
- std::cin >> parent[i];
- level[1] = 1;
- for(int i = 2; i <= n; i++) {
- level[i] = level[parent[i]] + 1;
- int sz=LSB(level[i]);
- int p=parent[i];
- while(sz>>=1){
- p=fen[p];
- }
- fen[i]=p;
- }
- while(q--) {
- int a, b;
- std::cin >> a >> b;
- std::cout << lca(a, b) << '\n';
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment