Cod sursa(job #1563917)

Utilizator lolmanDomuta Dariu lolman Data 7 ianuarie 2016 11:43:47
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.43 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

vector <int> vecin[100001],nivelvect;
vector <pair <int,int> > ciclu;

ifstream f("lca.in");
ofstream g("lca.out");

int n,m,x,i,seen[100001],nivel[100001],a,rmq[18][100001],o,p,poz[100001];

int biggestpower(int b)
   {
       int p=1;
       int k=0;
       while (2*p<=b)
       {
           p=p*2;
           k++;
       }
       return k;
   }
int topower(int b, int power)
   {
       if (power==0) return 1;
       for (int l=1;l<power;l++)
            b=b*2;
       return b;
   }

void precalculations()
    {
       int maxpower=biggestpower(ciclu.size());
       for (int i=1;i<=maxpower;i++)
               for (int j=1;j<=ciclu.size()-topower(2,i)+1;j++)
                      rmq[i][j] = min( rmq[i-1][j] , rmq[i-1][j+topower(2,i-1)]);
    }

void solve()
    {
        for (i=1;i<=m;i++)
        {
            f>>o>>p;
            int pozO=poz[o]+1;
            int pozP=poz[p]+1;
            int help1=max(pozO,pozP); int help2=min(pozO,pozP);          //sa fim siguri ca pozP > pozO doooh
            pozO=help2; pozP=help1;
            if (pozP-pozO==1) g<<ciclu[pozO-1].first<<" ";
            int maxpower=biggestpower(pozP-pozO);
            int sol=min(rmq[maxpower][pozO] , rmq[maxpower][pozP-topower(2,maxpower)+1]);
            for(int j=poz[o];j<=poz[p];j++)
                 if (ciclu[j].second==sol)
                       {
                           g<<ciclu[j].first<<" ";
                           break;
                       }
        }
    }


void euler(int x)
      {
          ciclu.push_back(make_pair(x,nivel[x]));
          if (poz[ciclu.back().first]==0)
          {
              poz[ciclu.back().first]=ciclu.size()-1;
          }
          if (!vecin[x].empty())
                 {
                     for(int i=0;i<vecin[x].size();i++)
                     {
                         int y=vecin[x][i];
                         nivel[y]=nivel[x]+1;
                         euler(y);
                         ciclu.push_back(make_pair(x,nivel[x]));
                     }

                 }
      }
int main()
{


    f>>n>>m;
    for (i=2;i<=n;i++)
    {
        f>>x;
        vecin[x].push_back(i);
    }
    nivel[1]=0;
    euler(1);
    for (i=0;i<ciclu.size();i++)
        rmq[0][i+1]=ciclu[i].second;
    precalculations();
    solve();
    return 0;
}