Cod sursa(job #1889146)

Utilizator LolkekzorChiorean Tudor Lolkekzor Data 22 februarie 2017 16:40:41
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.76 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");

int i, j, n, m, x, y, eSize;
int p[100010], lvl[100010], app[100010], logDyn[200010];
int rmq[20][200010], minNod[20][200010];
vector<int> sons[100010], eulerParc;

void euler(int nod, int l) {
    eulerParc.push_back(nod);
    lvl[nod] = l;
    app[nod] = eulerParc.size() - 1;
    for (vector<int>::iterator it = sons[nod].begin() ; it != sons[nod].end() ; it++) {
        euler(*it, l + 1);
        eulerParc.push_back(nod);
    }
}

int rmqSolve(int x, int y) {
    int k = logDyn[y - x];
    if (rmq[k][x] < rmq[k][y - (1 << k) + 1]) {
        return minNod[k][x];
    } else {
        return minNod[k][y - (1 << k) + 1];
    }
}

int main()
{
    fin >> n >> m;
    for (i = 2 ; i <= n ; i++) {
        fin >> p[i];
        sons[p[i]].push_back(i);
    }
    eulerParc.push_back(0);
    euler(1, 0);
    eSize = eulerParc.size();
    for (i = 2 ; i <= n * 2 + 1 ; i++)
        logDyn[i] = logDyn[i / 2] + 1;

    for (i = 1 ; i < eSize ; i++) {
        rmq[0][i] = lvl[eulerParc[i]];
        minNod[0][i] = eulerParc[i];
    }

    for (j = 1 ; (1 << j) < eSize ; j++) {
        for (i = 1 ; i + (1 << j) - 1 < eSize ; i++) {
            if (rmq[j - 1][i] < rmq[j - 1][i + (1 << (j - 1))]) {
                rmq[j][i] = rmq[j - 1][i];
                minNod[j][i] = minNod[j - 1][i];
            } else {
                rmq[j][i] = rmq[j - 1][i + (1 << (j - 1))];
                minNod[j][i] = minNod[j - 1][i + (1 << (j - 1))];
            }
        }
    }

    for (i = 1 ; i <= m ; i++) {
        fin >> x >> y;
        fout << rmqSolve(min(app[x], app[y]), max(app[x], app[y])) << '\n';
    }

    return 0;
}