Cod sursa(job #3137384)

Utilizator BlaugranasEnal Gemaledin Blaugranas Data 12 iunie 2023 19:06:25
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.27 kb
#include<bits/stdc++.h>
using namespace std;
ifstream F("lca.in");
ofstream G("lca.out");
#define L(x) ((x)&-(x))
const int N=1e5,M=1<<10;
char b[M],c[M];
int p=M,q,r[N-1],h[N],d[N],e[N],f[N],g[N],s[2*N+1],n,m,x;
inline char A()
{
	if(p==M)
		F.read(b,M),p=0;
	return b[p++];
}
inline int B()
{
	int q=0;
	char c;
    for(c=A();!isdigit(c);c=A());
	for(;isdigit(c);q=(q<<1)+(q<<3)+(c-'0'),c=A());
	return q;
}
inline void C(char& c)
{
	c[q++]=c;
	if(q==M)
		G.write(c,M),q=0;
}
inline void D(int x)
{
	int q;
	int n=0;
	char o[6];
	do
		q=(3435973837LL*x)>>35,o[n++]=x-(q<<1)-(q<<3)+'0',x=q;
	while(x);
	for(;n--;C(o[n]));
	C('\n');
}
void E(const int n)
{
	static int parent[N],vertices[N];
    int stackSize=1,currIdx=1;
    while(stackSize) {
        const int node=vertices[--stackSize];
        d[node]=currIdx++;
        for(int i=h[node];~i;i=r[i]) {
            const int son=i+1;
            parent[son]=node;
            vertices[stackSize++]=son;
        }
    }
    int queueFront=0,queueBack=1;
    vertices[0]=0;
    while(queueBack!=queueFront) {
        const int node=vertices[queueFront++];
        for(int i=h[node];~i;i=r[i]) {
            const int son=i+1;
            vertices[queueBack++]=son;
        }
    }
	memcpy(e,d,4*n);
	for(int i=n-1;i>=0;i-=1) {
		const int node=vertices[i];
		if(L(e[parent[node]])<L(e[node])) {
			e[parent[node]]=e[node];
		}
	}
	f[0]=0;
	for(int i=0;i<n;i+=1) {
		f[vertices[i]]=f[parent[vertices[i]]]|L(e[vertices[i]]);
	}
	g[d[0]-1]=0;
	for(int i=0;i<n;i+=1) {
		const int node=vertices[i];
		for(int j=h[node];~j;j=r[j]) {
			const int son=j+1;
			if (e[node]!=e[son]) {
				g[d[son]-1]=node;
			} else {
				g[d[son]-1]=g[d[node]-1];
			}
		}
	}
}
inline int Q(const int& x,const int& y)
{
	const int I=e[x],J=e[y];
	const int U=L(I),V=L(J);
	const int Z=s[(I^J)|U|V];
	const int W=L(f[x]&f[y]&~Z),K;
	int X,Y;
	W!=U?K=s[f[x]&(W-1)],X=g[((d[x]&~K)|(K+1))-1]:X=x;
	W!=V?K=s[f[y]&(W-1)],Y=g[((d[y]&~K)|(K+1))-1]:Y=y;
	return d[X]<d[Y]?X:Y;
}
int main()
{
	for(n=B(),m=B(),memset(h,-1,4*n),i=1;i<n;x=B()-1,r[i-1]=h[x],h[x]=i-1,++i);
	for(s[1]=0,i=2;i<=n+n;(i&(i-1)?s[i]=s[i-1]:s[i]=((s[i-1]+1)<<1)-1,++i);
	for(E(n);m--;D(1+Q(B()-1,B()-1));
	return G.write(c,q),0;
}