Cod sursa(job #1669758)

Utilizator SlevySlevoaca Stefan-Gabriel Slevy Data 30 martie 2016 23:55:46
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.42 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#include <bitset>
#include <algorithm>

using namespace std;

ifstream in("lca.in");
ofstream out("lca.out");
const int NMAX = 100001;
int n,m;
vector<int> muchii[NMAX];
stack<int> st;
bitset<NMAX> mark;
vector<int> euler;
int high[NMAX];
vector<int> height;
int pos[NMAX];
int **sp;
int *lg;

void citire()
{
    in>>n>>m;
    int x;
    for(int i=1;i<n;i++)
    {
        in>>x;
        muchii[x].push_back(i+1);
    }
}

void dfs()
{
    mark.set(1);
    st.push(1);
    int y = 0;
    int target,ok;
    while(!st.empty())
      {
        y = st.top();
        euler.push_back(y);
        if(y!=1)
        {
            if(!pos[y])
            pos[y] = euler.size()-1;
        }
        ok = 0;
        for(unsigned int i=0;i<muchii[y].size();i++)
            if(!mark.test(muchii[y][i]))
            {
                target = muchii[y][i];
                ok = 1;
                break;
            }
        if(ok)
        {
            high[target] = high[y]+1;
            st.push(target);
            mark.set(target);
        }
        else
            st.pop();
    }
}

void sparse_table()
{
    lg = new int[height.size()+1];
    lg[1] = 0;
    lg[0] = 0;
    for(unsigned int i=2;i<=height.size();i++)
        lg[i] = lg[i/2] + 1;
    sp = new int*[height.size()+1];
    for(unsigned int i=0;i<=height.size();i++)
        sp[i] = new int[18];
    for(unsigned int i=0;i<height.size();i++)
        sp[i][0] = i;
    for(unsigned int j=1;(unsigned int)(1<<j)<=height.size();j++)
        for(unsigned int i=0;i+(1<<j)-1<height.size();i++)
            if(height[sp[i][j-1]] <= height[sp[i+(1<<(j-1))][j-1]])
                sp[i][j] = sp[i][j-1];
            else
                sp[i][j] = sp[i+(1<<(j-1))][j-1];
}

int main()
{
    citire();
    dfs();
    for(unsigned int i=0;i<euler.size();i++)
        height.push_back(high[euler[i]]);
    sparse_table();
    int x,y;
    int k;
    int ind;
    for(int i=1;i<=m;i++)
    {
        in>>x>>y;
        if(pos[x] > pos[y])
            swap(x,y);
        k = lg[pos[y]-pos[x]+1];
       if(height[sp[pos[x]][k]] <= height[sp[pos[y]-(1<<k)+1][k]])
            ind = sp[pos[x]][k];
            else
                ind = sp[pos[y]-(1<<k)+1][k];
        out<<euler[ind]<<"\n";
    }
    in.close();
    out.close();
    return 0;
}