Cod sursa(job #2858513)

Utilizator 100pCiornei Stefan 100p Data 27 februarie 2022 18:34:37
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.19 kb
#include <bits/stdc++.h>
#define ull unsigned long long
#define FILES freopen("lca.in","r",stdin);\
              freopen("lca.out","w",stdout);
#define CMAX 15485863
#define fastio std::ios_base::sync_with_stdio(NULL),cin.tie(NULL),cout.tie(NULL);
#define mp make_pair
#define INF 1e18
#define mod 1000000007
#define ll long long
#define SMAX 300
#define MAX 100000
#define pb push_back
#define add emplace_back
#define void inline void
using namespace std;
vector<pair<int,int>> v[MAX+5];
bool check[MAX+5];
ll subtree[MAX+5],ans,road[MAX+5];
int n,q,a,b,cnt,f[MAX+5],times[MAX+5],cate[MAX+5];
pair<int,int>euler[MAX*3+5],rmq[19][MAX*3+5];
void dfs(int x,int h,int s)
{
    road[x] = s;
    check[x] = 1;
    cnt++;
    f[x] = cnt;
    euler[cnt] = {x,h};
    bool ok = 0;
    for(auto i : v[x])
    {
        if(!check[i.first])
        {
            check[i.first] = 1;
            dfs(i.first,h+1,s+i.second);
            cnt++;
            euler[cnt] = {x,h};
            times[x] += times[i.first];
            cate[x] += cate[i.first];
            subtree[x] += subtree[i.first] + i.second * times[i.first];
            ok = 1;
        }
    }
    if(!ok)
    times[x] = 1;
    cate[x]++;
}
inline pair<int,int> Min(pair<int,int>a,pair<int,int>b)
{
    return (a.second > b.second ? b : a);
}
inline pair<int,int> GetLca(int x,int y)
{
    int mi = min(f[x],f[y]), mx = max(f[x],f[y]);
    int d = mx - mi + 1, p = 1, e = 0;
    while(p <= d) p *= 2, e++;
    p >>= 1, e--;
    return Min(rmq[e][mi],rmq[e][mx-p+1]);
}
int main()
{
    fastio
    FILES
    cin >> n >> q;
    for(int i = 1;i <= n; ++i) times[i] = 1;
    for(int i = 1;i < n; ++i)
    {
        cin >> a;
        v[i+1].add(mp(a,0)),v[a].add(mp(i+1,0));
    }
    dfs(1,1,0);
    for(int i = 1;i <= cnt; ++i) rmq[0][i] = euler[i];
    int r = log2(cnt),y = cnt;
    for(int i = 1;i <= r; ++i)
    {
        y -= (1 << (i-1));
        for(int j = 1;j <= y;++j){
            rmq[i][j] = Min(rmq[i-1][j],rmq[i-1][j+(1<<(i-1))]);
        }
    }
    for(int i = 1;i <= q; ++i)
    {
        cin >> a >> b;
        pair<int,int> lca = GetLca(a,b);
        cout << lca.first << '\n';
    }
}