Cod sursa(job #1975436)

Utilizator pepsiM4A1Ozturk Arif pepsiM4A1 Data 30 aprilie 2017 22:00:41
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.88 kb
#include <cstdio>
#include <vector>
#include <fstream>
#include <cstring>
#define pb push_back
using namespace std;
const int DIM=50000,nmax=100004,lmax=18;
char buff[DIM];
int poz=DIM-1;
void citeste(int &nr)
{
    nr=0;
    while(!('0'<=buff[poz]&&buff[poz]<='9'))
    {
        if(++poz==DIM) fread(buff,1,DIM,stdin),poz=0;
    }
    while('0'<=buff[poz]&&buff[poz]<='9')
    {
        nr=nr*10 + buff[poz]-'0';
        if(++poz==DIM) fread(buff,1,DIM,stdin),poz=0;
    }
}
class Writer {
  public:
    Writer(const char *name):
        m_stream(name) {
        memset(m_buffer, 0, sizeof(m_buffer));
        m_pos = 0;
    }

    Writer& operator<<(int a) {
        int many = 0;
        do {
            digit_buffer[many++] = a % 10 + '0';
            a /= 10;
        } while (a > 0);
        for (int i = many - 1; i >= 0; --i)
            putchar(digit_buffer[i]);
        return *this;
    }

    Writer& operator<<(const char *s) {
        for (; *s; ++s)
            putchar(*s);
        return *this;
    }

    ~Writer() {
        m_stream.write(m_buffer, m_pos);
    }

  private:
    void putchar(char c) {
        m_buffer[m_pos++] = c;
        if (m_pos == kBufferSize) {
            m_stream.write(m_buffer, m_pos);
            m_pos = 0;
        }
    }

    static const int kBufferSize = 32768;
    ofstream m_stream;
    char m_buffer[kBufferSize];
    char digit_buffer[30];
    int m_pos;
} fout("lca.out");
int lvl[nmax],t[lmax][nmax];
vector<int>adj[nmax];
int n,m;
inline void citire()
{
    citeste(n),citeste(m);
    for(int i=1;i<n;i++)
    {
        citeste(t[0][i+1]);
        adj[t[0][i+1]].pb(i+1);
    }
}
void define_lvl(int nod)
{
    for(vector<int>::iterator it=adj[nod].begin();it!=adj[nod].end();++it)
    {
        if(lvl[*it]==0)
        {
            lvl[*it]=lvl[nod]+1;
            define_lvl(*it);
        }
    }
}
int dad(int nod,int val)
{
    //printf("%d\n",(1<<1));
    for(int i=17;i>=0;--i)
    {
        if(val&(1<<i)) nod=t[i][nod];
    }
    return nod;
}
int lca(int n1,int n2)
{
    if(lvl[n1]>lvl[n2]) swap(n1,n2);
    if(lvl[n1]!=lvl[n2]) n2=dad(n2,lvl[n2]-lvl[n1]);
   //printf("%d %d\n",n1,n2);
    if(n1==n2) return n1;
    int rasp=n1;
    for(int i=17;i>=0;--i)
    {
        if(t[i][n1]!=t[i][n2]&&t[i][n1]!=0&&t[i][n2]!=0)
        {
            rasp=t[i][n1];
            n1=t[i][n1];
            n2=t[i][n2];
        }
    }
    return t[0][rasp];
}
inline void define_t()
{
    for(int i=1;i<=17;i++)
    {
        for(int j=1;j<=n;j++) t[i][j]=t[i-1][t[i-1][j]];
    }
}
inline void solve()
{
    for(;m>0;--m)
    {
        int n1,n2;
        citeste(n1),citeste(n2);
        fout<<lca(n1,n2)<<"\n";
    }
}
int main()
{
    freopen ("lca.in","r",stdin);
    citire();
    lvl[1]=1;
    define_lvl(1);
    define_t();
    solve();
}