Cod sursa(job #3204268)

Utilizator RobertAcAcatrinei Robert-Marian RobertAc Data 16 februarie 2024 09:19:06
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.76 kb
#include <bits/stdc++.h>
#ifdef LOCAL
#define in cin
#define out cout
#endif

using namespace std;

#ifndef LOCAL
ifstream in("lca.in");
ofstream out("lca.out");
#endif

const int nmax = 1e5 + 5;

bool color[nmax];
int ancestor[nmax];

struct DSU
{
    struct node
    {
        int p = 0, s = 1;
    } nodes[nmax];
    int getP(int ind)
    {
        if (nodes[ind].p == 0)
            return ind;
        return nodes[ind].p = getP(nodes[ind].p);
    }
    bool sameTree(int a, int b)
    {
        return getP(a) == getP(b);
    }
    void unite(int a, int b)
    {
        a = getP(a);
        b = getP(b);
        if (nodes[a].s > nodes[b].s)
            swap(a, b);
        nodes[a].p = b;
        nodes[b].s += nodes[a].s;
    }
} root;

struct query
{
    int a, ind;
    query(int a = 0, int ind = 0) : a(a), ind(ind) {}
};

vector<int> adj[nmax];
vector<query> queries[nmax];
int qans[nmax*10*2];

void dfs(int node=1, int p = -1)
{
    ancestor[node] = node;
    for (auto i : adj[node])
    {
        if (i != p)
        {
            dfs(i, node);
            if (!root.sameTree(node, i))
            {
                root.unite(node, i);
            }
            ancestor[root.getP(node)] = node;
        }
    }
    color[node] = 1;
    for(auto i:queries[node])
    {
        if(color[i.a]==1&&qans[i.ind]==0)
        {
            qans[i.ind]=ancestor[root.getP(i.a)];
        }
    }
}

int main()
{
    int n, m;
    in >> n >> m;
    for (int i = 2; i <= n; i++)
    {
        int a;
        in >> a;
        adj[i].push_back(a);
        adj[a].push_back(i);
    }
    for(int i=0;i<m;i++)
    {
        int a,b;in>>a>>b;
        queries[a].push_back({b,i});
        queries[b].push_back({a,i});
    }
    dfs();
    for(int i=0;i<m;i++)
    {
        out<<qans[i]<<'\n';
    }
}