Cod sursa(job #1567316)

Utilizator badea_adi1999Badea Adrian Catalin badea_adi1999 Data 13 ianuarie 2016 09:20:40
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 2.19 kb
//Lowest Common Ancestor
//Complexitate : Memorie O(n*(log2(n))) , Timp O((n*log2(n)+m*log2(n)));
#include <cstdio>
#include <vector>
#include <fstream>
#define nmax 100005
#define kmax 16
using namespace std;
int n,m,lev[nmax];
int t[nmax][kmax];
vector <int> v[nmax];


class instream {
    public:
        instream() {}
        instream(const char *file_name) {
            input_file=fopen(file_name,"r");
            cursor=0;
            fread(buffer,SIZE,1,input_file);
        }
        inline instream &operator >>(int &n) {
            while((buffer[cursor]<'0'||buffer[cursor]>'9')&&buffer[cursor]!='-') {
                advance();
            }
            n=0;
            while('0'<=buffer[cursor]&&buffer[cursor]<='9') {
                n=n*10+buffer[cursor]-'0';
                advance();
            }
            return *this;
        }
    private:
        FILE *input_file;
        static const int SIZE=1<<15;
        int cursor;
        char buffer[SIZE];
        inline void advance() {
            ++ cursor;
            if(cursor==SIZE) {
                cursor=0;
                fread(buffer,SIZE,1,input_file);
            }
        }
};

    instream f("lca.in");
    ofstream fout("lca.out");

void dfs(int x)
{
    int i;
    for (i=0;i<v[x].size();i++) {
        lev[v[x][i]]=lev[x]+1;
        dfs(v[x][i]);
    }
}
int main()
{
    int i,j,k,a,b;
    int x,y;
    f>>n>>m;
    for (i=2;i<=n;i++) {
        f>>j;
        t[i][0]=j;
        v[j].push_back(i);
    }
    for (k=1;(1<<k)<=n;k++)
        for (i=1;i<=n;i++)
            t[i][k]=t[t[i][k-1]][k-1];
    dfs(1);
    for (i=1;i<=m;i++) {
        f>>a>>b;
        if (lev[a]>lev[b])
            swap(a,b);
        for (k=0;(1<<k)<lev[b];k++);
        for (;k>=0;k--)
            if (lev[b]-(1<<k)>=lev[a])
                b=t[b][k];
        if (a==b) {
            fout<<a<<'\n';
            continue;
        }

        for (k=0;(1<<k)<lev[b];k++);
        for (;k>=0;k--)
            if (t[a][k]&&t[b][k]&&t[a][k]!=t[b][k]) {
                a=t[a][k];
                b=t[b][k];
            }

        fout<<t[a][0]<<'\n';
    }


    return 0;
}