Pagini recente » Cod sursa (job #303390) | Cod sursa (job #2466366) | Cod sursa (job #2417366) | Cod sursa (job #333150) | Cod sursa (job #2693806)
#include<fstream>
#include<bitset>
#include<vector>
using namespace std;
class InParser {
private:
FILE *fin;
char *buff;
int sp;
char read_ch() {
++sp;
if (sp == 4096) {
sp = 0;
fread(buff, 1, 4096, fin);
}
return buff[sp];
}
public:
InParser(const char* nume) {
fin = fopen(nume, "r");
buff = new char[4096]();
sp = 4095;
}
InParser& operator >> (int &n) {
char c;
while (!isdigit(c = read_ch()) && c != '-');
int sgn = 1;
if (c == '-') {
n = 0;
sgn = -1;
} else {
n = c - '0';
}
while (isdigit(c = read_ch())) {
n = 10 * n + c - '0';
}
n *= sgn;
return *this;
}
InParser& operator >> (long long &n) {
char c;
n = 0;
while (!isdigit(c = read_ch()) && c != '-');
long long sgn = 1;
if (c == '-') {
n = 0;
sgn = -1;
} else {
n = c - '0';
}
while (isdigit(c = read_ch())) {
n = 10 * n + c - '0';
}
n *= sgn;
return *this;
}
} in( "lca.in" );
ofstream out("lca.out");
int rmq[29][200001],k,level[100001],p[30],euler[200001],nivel[200001],n,q,x,y,a,b,c,aux[200001], prim[100001];
vector<int>v[100001];
bitset<200001>hz;
void dfs( int nod ){
euler[++k] = nod;
if( v[nod].size() == 0 ){
return;
}
else{
for( int i = 0; i < v[nod].size(); i ++ ){
level[ v[nod][i] ] = level[nod]+1;
dfs( v[nod][i] );
euler[++k] = nod;
}
}
return;
}
int main(){
in >> n >> q;
level[1] = 1;
for( int i = 2; i <= n; i ++ ){
in >> x;
v[x].push_back(i);
}
dfs( 1 );
p[0] = 1;
for( int i = 1; i <= 25; i ++ ){
p[i] = p[i-1]*2;
if( k >= p[i] ){
a = i;
}
}
for( int i = 1; i <= k; i ++ ){
nivel[ i ] = level[ euler[i] ];
}
for( int i = 2; i <= k; i ++ ){
aux[i] = aux[i/2]+1;
}
for( int i = 1; i <= k; i ++ ){
rmq[0][i] = i;
}
for( int j = 1; j <= a; j ++ ){
for( int i = 1; i <= k-p[j]+1; i ++ ){
if( nivel[ rmq[j-1][i+p[j-1]] ] < nivel[ rmq[j-1][i] ] ){
rmq[j][i] = rmq[j-1][i+p[j-1]];
}
else{
rmq[j][i] = rmq[j-1][i];
}
}
}
for( int i = 1; i <= k; i ++ ){
if( hz[euler[i]] == 0 ){
hz[euler[i]] = 1;
prim[ euler[i] ] = i;
}
}
for( int i = 1; i <= q; i ++ ){
in >> a >> b;
c = min(prim[a],prim[b]);
b = max(prim[a],prim[b]);
a = c;
y = aux[b-a+1];
x = p[y];
if( nivel[rmq[y][b-x+1]] < nivel[ rmq[y][a] ] ){
out<<euler[ rmq[y][b-x+1] ]<<"\n";
}
else{
out<<euler[ rmq[y][a] ]<<"\n";
}
}
return 0;
}