Cod sursa(job #1170447)

Utilizator iordache.bogdanIordache Ioan-Bogdan iordache.bogdan Data 13 aprilie 2014 17:25:14
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.91 kb
#include <fstream>
#include <vector>
#include <bitset>

using namespace std;

bitset<100005> ok;

vector<int> l[100005];

int n,m,i,a,b,x,y,lg,j,p,tmp;

int Niv[400005],euler[400005],first_ap[100005],P[400005];

struct range {
    int x;
    int y;
} rmq[21][400005];

void dfs(int nod, int niv) {
    ok[nod]=1;
    euler[++lg]=nod;
    Niv[lg]=niv;
    if(first_ap[nod]==0)
        first_ap[nod]=lg;
    for(int i=0;i<l[nod].size();i++) {
        int y=l[nod][i];
        if(ok[y]==0) {
            dfs(y,niv+1);
            euler[++lg]=nod;
            Niv[lg]=niv;
        }
    }
}

int main() {
    ifstream f("lca.in");
    ofstream g("lca.out");
    f>>n>>m;
    for(i=1;i<n;i++) {
        f>>x;
        l[i+1].push_back(x);
        l[x].push_back(i+1);
    }
    dfs(1,1);
    for(i=1;i<=lg;i++) {
        rmq[0][i].y=euler[i];
        rmq[0][i].x=Niv[i];
    }
    for(i=1;i<=20;i++)
        for(j=1;j<=lg;j++) {
            if(j+(1<<(i-1))>lg) {
                rmq[i][j]=rmq[i-1][j];
                continue;
            }
            if(rmq[i-1][j].x<=rmq[i-1][j+(1<<(i-1))].x) {
                rmq[i][j]=rmq[i-1][j];
            }
            else {
                rmq[i][j]=rmq[i-1][j+(1<<(i-1))];
            }
        }
    P[1]=1;
    for(i=2;i<=lg+1;i++)
        P[i]=P[i>>1]+1;
    while(m--) {
        f>>x>>y;
        a=first_ap[x];
        b=first_ap[y];
        if(a>b) {
            tmp=a;
            a=b;
            b=tmp;
        }
        p=P[b-a+1];
        if(b-(1<<p)+1<1 || b-(1<<p)+1>lg) {
            g<<rmq[p][a].y<<"\n";
            continue;
        }
        if(rmq[p][a].x<=rmq[p][b-(1<<p)+1].x)
            g<<rmq[p][a].y<<"\n";
        else
            g<<rmq[p][b-(1<<p)+1].y<<"\n";
    }
   /* for(i=0;i<=20;i++) {
        for(j=1;j<=lg;j++)
            g<<rmq[i][j].x<<" ";
        g<<"\n";
    }*/
    return 0;
}