Cod sursa(job #2213283)

Utilizator AndreiDumitrescuAndrei Dumitrescu AndreiDumitrescu Data 16 iunie 2018 01:14:12
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.97 kb
#include <iostream>
#include <fstream>
#include <vector>
#define infinit 999999999
using namespace std;

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

int tati[100010], parcurgere[400010], nivel[400010], prima[100010], viz[100010];
int dp[400010][22], log[100010];
int k = 1;
int parcurgere_euleriana(int nod, int nivel_actual, int n)
{
    parcurgere[k] = nod;
    nivel[k] = nivel_actual;
    if(viz[nod] == 0)
    {
        prima[nod] = k;
        viz[nod] = 1;
    }
    k++;
    for(int i = 1; i <= n; i++)
    {
        if(tati[i] == nod)
        {
            parcurgere_euleriana(i, nivel_actual + 1, n);
            parcurgere[k] = nod;
            nivel[k] = nivel_actual;
            k++;
        }
    }
    return 0;
}

int minim(int a, int b)
{
  if(a == infinit)
    return b;
  if(b == infinit)
    return a;
  if(nivel[a] < nivel[b])
        return a;
  return b;
}

int minim_corect(int a, int b, int x, int y)
{
   // cout <<a <<" "<< x << endl;
   // cout << b << " " << y << endl;
    if(a < b)
        return x;
    return y;
}

int t = 0;
int interogare(int x, int y)
{
    t++;
    if(x == y)
      return x;
    else
    {

      int dif;
      dif = y - x ;
    //  g << "A " << t << "-lea querri " << endl << x <<" " << log[dif] << " " << dp[x][log[dif]] << endl << y-(1<<log[dif]) << " " << log[dif] << " " << dp[y-(1<<log[dif])][log[dif]] << endl;
      return minim(dp[x][log[dif]], dp[y-(1<<log[dif])][log[dif]]);
    }
}

int main()
{
    int n, m, x, i, j, y;
    f >> n >> m;
    tati[1] = 0;
    for(int i = 2; i <= n ; i++)
    {
        f >> tati[i];
    }
    parcurgere_euleriana(1, 0, n);
    /* for(int i = 0; i < k; i++)
        g << parcurgere[i] << " ";
    g << '\n';
    for(int i = 0; i < k; i++)
        g << nivel[i] << " ";
    */
    for(i = 0; i < 100010; i++)
        for(j = 0; j < 22; j++)
            dp[i][j] = infinit;
    for(i = 1; i <= k; i++)
        dp[i][0] = minim_corect(nivel[i], nivel[i+1], i, i+1);
    dp[k][0] = parcurgere[k];
    for(i = 2; i <= k; i++)
    {
        log[i] = log[i/2] + 1;
    }
    for(int j = 1; j <= log[k]; j++)
    {
        for(int i = 1;(i + (1 << (j-1))) <= k ; i++)
        {
       //     cout << "CRAPAAAA" << " " << i << endl;
        //    cout << dp[i][j-1] << " " << dp[i  + (1 << (j-1))][j-1] << endl;
            dp[i][j] = minim(dp[i][j-1], dp[i  + (1 << (j-1))][j-1]);
        }
    }
   // cout << "AJUNGE AICI?" <<endl;
   /* for(int i = 1; i <= k; i++)
        cout << i <<" " << parcurgere[i] << " " << nivel[i] << endl; */

   // cout << endl;
    for(int i = 0; i < m; i++)
    {
        f >> x >> y;
        //cout << prima[x] << " " << prima[y] << " " << endl;

        if(prima[x] < prima[y])
            g << parcurgere[interogare(prima[x], prima[y])] << '\n';
        else
            g << parcurgere[interogare(prima[y], prima[x])] << '\n';

     //   cout << endl << endl;
    }
    return 0;
}