Cod sursa(job #2642251)

Utilizator MoldovanAndrei1Moldovan Andrei MoldovanAndrei1 Data 14 august 2020 10:52:47
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.71 kb
#include <cstdio>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <ctype.h>
#include <cmath>
using namespace std;
const int NMAX = 100005;
vector <int> Edge[NMAX];
int last = 0 , time1 = 0 , n;
int freq[NMAX],size_tree[NMAX],com[NMAX], parent[NMAX], Heavy_Edge[NMAX] , poz[NMAX] , start[NMAX];
int d[NMAX], parent1[NMAX] , height[NMAX] , end1[NMAX];
int _in_loc; char _in_buff[32768];
char read_ch()
{
	++_in_loc;
	if (_in_loc == 32768) {
		_in_loc = 0;
		fread(_in_buff, 1, 32768, stdin);
	}
	return _in_buff[_in_loc];
}

int read_u32()
{
	int u32 = 0; char c;
	while (!isdigit(c = read_ch()) && c != '-');
	int sgn = 1;
    u32 = c - '0';
	while (isdigit(c = read_ch())) {
		u32 = u32 * 10 + c - '0';
	}
	return u32 * sgn;
}
void dfs(int nod)
{
    int ok = 0 ;
    freq[nod] = 1;
    for(auto it:Edge[nod])
            if(!freq[it])
                {
                    d[it] = d[nod] + 1;
                    parent[it]=nod;
                    dfs(it);
                    size_tree[nod]+= size_tree[it];
                    if((size_tree[nod]+1)/2 <= size_tree[it])
                    {
                        if(ok)
                        parent1[com[ok]] = nod;
                        ok = it;
                    }
                    else
                        parent1[com[it]] = nod;
                }
    if(size_tree[ok] >= (size_tree[nod] + 1)/2)
    {
        com[nod] = com[ok];
        Heavy_Edge[ok]=nod;
    }
    else
    {
                parent1[com[ok]] = nod;
                com[nod] = ++last;
                start[last] = nod;
    }
}
void dfs1(int nod)
{
    poz[++time1] = nod;
    height[nod] = time1;
    end1[com[nod]] = nod;
    int t1 = Heavy_Edge[nod];
    if(Heavy_Edge[nod])
      dfs1(Heavy_Edge[nod]) ;
}
int answer(int x , int y)
{
    int val = 0 ;
    while(true)
    {
        if(com[x] == com[y])
            {if(height[x] < height[y])
            return y;
        else
            return x;
            }
        int x1 = end1[com[x]] ,y1= end1[com[y]];
        if(d[x1] < d[y1])swap(x,y),swap(x1,y1);
        x = parent[x1];
    }

}
int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    int  q , i , x , y, op;
    n=read_u32();
    q=read_u32();
    for( i = 1 ; i <= n; ++i)
               size_tree[i] = 1;
    for( i = 1 ; i < n; i++)
    {
        x = read_u32();
        Edge[x].push_back(i+1);
    }
    d[1] = 1;
    parent[1] = 1;
    dfs(1);
    for(i = 1 ; i <=last ; ++i)
            dfs1(start[i]);
    for(i = 1 ; i <= q; i++)
    {
        x=read_u32();
        y=read_u32();
            printf("%d\n",answer(x,y));
    }
    return 0;
}