Pagini recente » Cod sursa (job #3271739) | Cod sursa (job #3175634) | Cod sursa (job #3164423) | Cod sursa (job #2857023) | Cod sursa (job #3283597)
#include <stdio.h>
#include <ctype.h>
#include <vector>
struct ReadOnSteroids {
static constexpr int BSIZ = 128 * 1024;
FILE *fin;
char buf[BSIZ];
int ibp;
ReadOnSteroids( const char *fname ): ibp(BSIZ - 1) { fin = fopen( fname, "r" ); }
~ReadOnSteroids() { fclose( fin ); }
char getc() {
if( (ibp = ((ibp + 1) & (BSIZ - 1))) == 0 )
fread( buf, sizeof(char), BSIZ, fin );
return buf[ibp];
}
int getint() {
int n = 0, ch;
while( !isdigit( ch = getc() ) );
do
n = n * 10 + ch - '0';
while( isdigit( ch = getc() ) );
return n;
}
};
struct WriteOnSteroids {
static constexpr int BSIZ = 128 * 1024;
FILE *fout;
char buf[BSIZ];
int obp;
WriteOnSteroids( const char *fname ): obp(0) { fout = fopen( fname, "w" ); }
~WriteOnSteroids() {
fwrite( buf, sizeof(char), obp, fout );
fclose( fout );
}
void putc( char ch ) {
buf[obp] = ch;
if( (obp = ((obp + 1) & (BSIZ - 1))) == 0 )
fwrite( buf, sizeof(char), BSIZ, fout );
}
void putint( int n, char nextc ) {
char digits[10 + 1] = "0000000000";
int idx = 10;
while( n ){
digits[--idx] += n % 10;
n /= 10;
}
for( ; idx < 10; idx++ )
putc( digits[idx] );
putc( nextc );
}
};
struct Splay {
struct Node {
int c[2], par;
bool flip;
Node(): par(0), flip(false) { c[0] = c[1] = 0; }
};
std::vector<Node> t;
Splay( int n ): t(n + 1) {}
void push_flip( int u ) {
if( !u ) return;
t[u].flip ^= 1;
}
void push( int u ) {
if( t[u].flip ){
std::swap( t[u].c[0], t[u].c[1] );
t[u].flip = false;
push_flip( t[u].c[0] );
push_flip( t[u].c[1] );
}
}
int side( int u ) {
int p = t[u].par;
if( t[p].c[0] == u ) return 0;
if( t[p].c[1] == u ) return 1;
return -1;
}
// doesn't take responsibility for pushes
void link( int p, int u, int side ) {
if( u ) t[u].par = p;
if( p && ~side ) t[p].c[side] = u;
}
// both x and y must be pushed
void zig( int x ) {
int y = t[x].par, sx = side( x );
int mij = t[x].c[!sx], up = t[y].par, sy = side( y );
link( up, x, sy );
link( x, y, !sx );
link( y, mij, sx );
}
void splay( int x ) {
while( side( x ) >= 0 ){
int y = t[x].par;
if( side( y ) < 0 ){
push( y );
push( x );
zig( x );
continue;
}
int z = t[y].par;
push( z );
push( y );
push( x );
int sx = side( x ), sy = side( y );
zig( sx == sy ? y : x );
zig( x );
}
}
};
struct LinkCut : Splay {
LinkCut( int n ): Splay(n) {}
int expose( int uu ) {
int u = uu, prev = 0;
while( u ){
splay( u );
push( u );
t[u].c[1] = prev; // cutoff right
prev = u;
u = t[u].par;
}
splay( uu );
return prev;
}
void reroot( int u ) {
expose( u );
push_flip( u );
}
void Link( int u, int v ) {
expose( u );
reroot( v );
t[v].par = u; // weak link
}
// assumes a and b are in same tree (wich is the case here)
int Lca( int a, int b ) {
expose( a );
return expose( b );
}
};
ReadOnSteroids fin("lca.in");
WriteOnSteroids fout("lca.out");
int main() {
int n = fin.getint(), q = fin.getint();
LinkCut zile(n);
for( int i = 2; i <= n; i++ ){
int par = fin.getint();
zile.Link( par, i );
}
zile.reroot( 1 ); // conform enuntului
for( int i = 0; i < q; i++ ){
int a = fin.getint(), b = fin.getint();
fout.putint( zile.Lca( a, b ), '\n' );
}
return 0;
}