Cod sursa(job #2362105)

Utilizator AngelEclipseGarleanu Alexandru Stefan AngelEclipse Data 2 martie 2019 22:01:58
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.36 kb
#include <bits/stdc++.h>

using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

vector<int> graf[100005];
vector<int> euler;

bool viz[100005];
int level[100005];

struct lca
{
    lca(int Node = 0, int Depth = -1)
    {
        node = Node;
        depth = Depth;
    }
    int node, depth;
};

lca sparseTable[100005][20];

int n, m;

void read()
{
    f >> n >> m;
    for (int i = 2, tempParent; i <= n; i++)
    {
        f >> tempParent;
        graf[i].push_back(tempParent);
        graf[tempParent].push_back(i);
    }
}

int dfs(int node, int lv)
{
    euler.push_back(node);
    level[node] = lv;
    viz[node] = true;
    for (int i = 0; i < graf[node].size(); i++)
    {
        if (!viz[graf[node][i]])
        {
            dfs(graf[node][i], lv + 1);
            euler.push_back(node);
        }
    }
}

void gen_sparse_table()
{
    for (int i = 1; i <= euler.size(); i++)
    {
        sparseTable[0][i] = lca(euler[i - 1], level[euler[i-1]]);
    }
    for (int i = 1; i <= log2(euler.size()); i++)
    {
        for (int j = 1; j < euler.size() - ((int)pow(2, i) - 1); j++)
        {
            if (sparseTable[i - 1][j].depth < sparseTable[i - 1][j + (int)pow(2, i - 1)].depth)
                sparseTable[i][j] = sparseTable[i - 1][j];
            else
                sparseTable[i][j] = sparseTable[i - 1][j + (int)pow(2, i - 1)];
        }
    }
}

int query(int node1, int node2)
{
    bool found1 = false, found2 = false;
    int n1i, n2i;

    for(int i = 0; i < euler.size() && (!found1 || !found2); i++)
    {
        if(!found1 && euler[i] == node1)
        {
            found1 = true;
            n1i = i + 1;
        }
        if(!found2 && euler[i] == node2)
        {
            found2 = true;
            n2i = i + 1;
        }
    }
    if(n1i > n2i) swap(n1i, n2i);
    int chunkSize = (int) log2(n2i - n1i + 1);

    int a = sparseTable[chunkSize][n1i].depth;
    int b = sparseTable[chunkSize][n2i - (int)pow(2, chunkSize) + 1].depth;
    
    if(a > b)
        return sparseTable[chunkSize][n2i].node;
    else
        return sparseTable[chunkSize][n1i].node;
}

int main()
{
    read();
    dfs(1, 0);
    gen_sparse_table();

    for(int i = 0, node1, node2; i < m; i++)
    {
        f>>node1>>node2;
        g<<query(node1, node2)<<'\n';
    }
}