Cod sursa(job #2719850)

Utilizator mariusn01Marius Nicoli mariusn01 Data 10 martie 2021 13:04:42
Problema Lowest Common Ancestor Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.94 kb
#include <fstream>
#include <vector>
#define DIM 100001
using namespace std;
vector<int> L[DIM];
int T[DIM], Niv[DIM], i, x, y, dif;
int D[DIM][18];
int n, m;
int S[DIM];
void dfs(int nod, int niv) {
    Niv[nod] = niv;
    S[niv] = nod;

    for (int e=0; niv-(1<<e) >= 1; e++) {
        D[nod][e] = S[niv - (1<<e)];
    }

    for (int i=0;i<L[nod].size();i++) {
        int fiu = L[nod][i];
        dfs(fiu, niv+1);
    }
}

/// La fiecare nod voi calcula:
/// D[nod][e] = al 2^e - lea stramos al lui nod

int main () {
    ifstream fin ("lca.in");
    ofstream fout("lca.out");
    fin>>n>>m;
    for (i=2;i<=n;i++) {
        fin>>T[i];
        L[ T[i] ].push_back(i); /// liste de fii
    }

    dfs(1, 1);
    /// T = vector de tati
    /// Niv = vector cu nivelul fiecarui nod
    int e;
    while (m--) {
        fin>>x>>y;

        /**
        Niv[x] = 7
        Niv[y] = 13
        Diferenta este 6 = (4+2)
        y = D[y][1];  salt de 2
        y = D[y][2]; salt de 4 din log(diferenta) pasi aduc cele 2 noduri la acelasi nivel
        **/

        if (Niv[x] > Niv[y]) {
            dif = Niv[x] - Niv[y];
            e = 0;
            while (dif) {
                if (dif % 2 == 1) {
                    x = D[x][e];
                }
                e++;
                dif /= 2;
            }
        } else
            if (Niv[x] < Niv[y]) {
                dif = Niv[y] - Niv[x];
                e = 0;
                while (dif) {
                    if (dif % 2 == 1) {
                        y = D[y][e];
                    }
                    e++;
                    dif /= 2;
                }
            }

        e = 0;
        while ((1 << e) < n)
            e++;

        if (x == y) {
            fout<<x<<"\n";
            continue;
        }

        while (T[x] != T[y]) {
            if ( D[x][e] != D[y][e] ) {
                /// daca as sari in stramosul D[x][e] as fi inca prea jos
                x = D[x][e];
                y = x;
            }
            e--;
        }
        fout<<T[x]<<"\n";

/**
        while (x!=y) {
            x = T[x];
            y = T[y];
        }
**/
///        fout<<x<<"\n";
    }

    return 0;
}

/**
 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18
 2  2  4  5  8  9  9 10 10 14 14 15 17 17 20 20 21 33
 1

 Caut pe 17


 Initial:   start = 1;
 Exponent:  putere = 5

 ma uit la v[  start+(1<<putere)-1  ] gasesc prea mare indicele
 start ramane pe loc, putere--,

 ma uit la v[  start+(1<<putere)-1  ] = v[16] gasesc prea mare valoarea
 start ramane pe loc, putere--,

ma uit la v[  start+(1<<putere)-1  ] = v[8] gasesc prea mica valoarea
 start += 1<<putere, putere--, start = 9 si putere = 2, v[12] e mai mic

ma uit la v[  start+(1<<putere)-1  ] = v[8] gasesc prea mica valoarea
 start += 1<<putere, putere--, start = 9 si putere = 2, v[12] e mai mic

 start + (1<<32) - 1



**/