Pagini recente » Cod sursa (job #664246) | Cod sursa (job #878981) | Cod sursa (job #2105048) | Cod sursa (job #178883) | Cod sursa (job #2674043)
#include<bits/stdc++.h>
#define fore(start,i,end) for(int i = start; i <= end; i++)
#define dbg(x) #x << "=" << x << " "
#define dbg2(x,y) "{" << x << "," << y << "} "
#define dbg3(x,y,k) "{" << x << "," << y << "," << k << "} "
#define dbg4(x,y,k,j) "{" << x << "," << y << "," << k << " , " << j << "} "
#define ll long long
#define f1 first
#define f2 second
#define inf 1000000005
#define debug_st(st) if (true) {cout << #st << " : "; stack<int> s123; while (!s123.empty()) cout << s123.top() << " ", s123.pop(); cout << "\n";}
#define debug_a(a,n) cout << #a << " : "; for(int i = 1; i <= n; i++) cout << a[i] << " "; cout << "\n";
#define debug_v(v) cout << #v << " : "; for(auto k : v) cout << k << " "; cout << "\n";
#define debug_s(s) cout << #s << " : "; for (auto k : s) cout << k < " "; cout << "\n";
#define debug_s2(s) cout << #s << " : "; for(auto k : s) cout << dbg2((*k).first,(*k).second); cout << "\n";
#define nmax 500005
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
int tour[nmax],t,first[nmax],n,m,dad[nmax],lastp[ nmax],r[nmax];
vector<int> kids[nmax];
pair<int,int> rmq[nmax][22];
void euler(int nod)
{
tour[++t] = nod;
first[nod] = t;
for (auto k : kids[nod])
{
euler(k);
tour[++t] = nod;
}
}
void make_rmq()
{int i,l;
///init pentru aia singuri
///{rank , ind}
for (i = 1; i <= t; i++) rmq[i][0] = {r[tour[i]] , tour[i]};
int maxl = log(t) + 1;
for(l = 1; l <= maxl; l++) {
for(i = 1; i <= t; i++) {
if (i + (1 << l) - 1 > t) continue;
rmq[i][l] = min(rmq[i][l - 1] , rmq[ i + ( 1 << (l - 1) ) ][l - 1] );
}
}
}
void get_rank(int nod, int Rank)
{
r[nod] = Rank;
for (auto k : kids[nod])
get_rank(k , Rank + 1);
}
int main()
{int i;
///input
in >> n >> m;
for (i = 1; i < n; i++) {
in >> dad[i + 1];
kids[dad[i + 1]].push_back(i + 1);
};
///get rank for each node
get_rank(1 , 1);
//debug_a(r , n);
///euler tour and we add every time we finish a subtree for a node (or when entering a node)
///find for every when you first come to it.
euler(1);
// debug_a(tour , t);
make_rmq();
lastp[1] = 0;
for (i = 2; i <= t; i++)
lastp[i] = lastp[i / 2] + 1;
for(i = 1; i <= m; i++)
{int st,dr;
in >> st >> dr;
st = first[st];
dr = first[dr];
int l = lastp[dr - st + 1];
// cout << dbg(i) << dbg(st) << dbg(dr) << dbg(l) << "\n";
out << min(rmq[st][l] , rmq[dr - (1 << l) + 1][l]).second << "\n";
}
}