Cod sursa(job #2693806)

Utilizator MihaelaCismaruMihaela Cismaru MihaelaCismaru Data 7 ianuarie 2021 08:00:26
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.11 kb
#include<fstream>
#include<bitset>
#include<vector>
using namespace std;
class InParser {
private:
    FILE *fin;
    char *buff;
    int sp;

    char read_ch() {
        ++sp;
        if (sp == 4096) {
            sp = 0;
            fread(buff, 1, 4096, fin);
        }
        return buff[sp];
    }

public:
    InParser(const char* nume) {
        fin = fopen(nume, "r");
        buff = new char[4096]();
        sp = 4095;
    }

    InParser& operator >> (int &n) {
        char c;
        while (!isdigit(c = read_ch()) && c != '-');
        int sgn = 1;
        if (c == '-') {
            n = 0;
            sgn = -1;
        } else {
            n = c - '0';
        }
        while (isdigit(c = read_ch())) {
            n = 10 * n + c - '0';
        }
        n *= sgn;
        return *this;
    }

    InParser& operator >> (long long &n) {
        char c;
        n = 0;
        while (!isdigit(c = read_ch()) && c != '-');
        long long sgn = 1;
        if (c == '-') {
            n = 0;
            sgn = -1;
        } else {
            n = c - '0';
        }
        while (isdigit(c = read_ch())) {
            n = 10 * n + c - '0';
        }
        n *= sgn;
        return *this;
    }
} in( "lca.in" );
ofstream out("lca.out");
int rmq[29][200001],k,level[100001],p[30],euler[200001],nivel[200001],n,q,x,y,a,b,c,aux[200001], prim[100001];
vector<int>v[100001];
bitset<200001>hz;
void dfs( int nod ){
    euler[++k] = nod;
    if( v[nod].size() == 0 ){
        return;
    }
    else{
        for( int i = 0; i < v[nod].size(); i ++ ){
            level[ v[nod][i] ] = level[nod]+1;
            dfs( v[nod][i] );
            euler[++k] = nod;
        }
    }
    return;
}
int main(){
    in >> n >> q;
    level[1] = 1;
    for( int i = 2; i <= n; i ++ ){
        in >> x;
        v[x].push_back(i);
    }
    dfs( 1 );
    p[0] = 1;
    for( int i = 1; i <= 25; i ++ ){
        p[i] = p[i-1]*2;
        if( k >= p[i] ){
            a = i;
        }
    }
    for( int i = 1; i <= k; i ++ ){
        nivel[ i ] = level[ euler[i] ];
    }
    for( int i = 2; i <= k; i ++ ){
        aux[i] = aux[i/2]+1;
    }
    for( int i = 1; i <= k; i ++ ){
        rmq[0][i] = i;
    }
    for( int j = 1; j <= a; j ++ ){
        for( int i = 1; i <= k-p[j]+1; i ++ ){
            if( nivel[ rmq[j-1][i+p[j-1]] ]  < nivel[ rmq[j-1][i]  ] ){
                rmq[j][i] = rmq[j-1][i+p[j-1]];
            }
            else{
                rmq[j][i] = rmq[j-1][i];
            }
        }
    }
    for( int i = 1; i <= k; i ++ ){
        if( hz[euler[i]] == 0 ){
            hz[euler[i]] = 1;
            prim[ euler[i] ] = i;
        }
    }
    for( int i = 1; i <= q; i ++ ){
        in >> a  >> b;
        c = min(prim[a],prim[b]);
        b = max(prim[a],prim[b]);
        a = c;
        y = aux[b-a+1];
        x = p[y];
        if( nivel[rmq[y][b-x+1]] < nivel[ rmq[y][a] ] ){
            out<<euler[ rmq[y][b-x+1] ]<<"\n";
        }
        else{
            out<<euler[ rmq[y][a] ]<<"\n";
        }

    }
    return 0;
}