Cod sursa(job #2017124)

Utilizator cipri321Marin Ciprian cipri321 Data 31 august 2017 12:45:57
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.83 kb
#include <fstream>
#include <vector>
#include <cstdio>
#define DIM 100001
using namespace std;
ifstream fi("lca.in");
int n,m;
int nre,E[2*DIM],L[2*DIM],H[DIM];
int VIZ[DIM];
vector<int> V[DIM];
int M[10*DIM];
FILE *_fout;
int _out_loc; char _out_buff[50000];

void write_init() // Apelaţi această funcţie la începutul funcţiei <main>
{
    _fout = fopen("lca.out", "w");
    _out_loc = 0;
}

void write_ch(char ch) // Apelaţi această funcţie pentru a scrie un caracter (cum ar fi ' ' sau '\n')
{
    if (_out_loc == 50000) {
        fwrite(_out_buff, 1, 50000, _fout);
        _out_loc = 0;
        _out_buff[_out_loc++] = ch;
    } else {
        _out_buff[_out_loc++] = ch;
    }
}

void write_u32(unsigned int vu32) // Apelaţi această funcţie pentru a scrie un număr ce se încadrează în categoria <unsigned int>
{
    if (vu32 <= 9) {
        write_ch(vu32 + '0');
    } else {
        write_u32(vu32 / 10);
        write_ch(vu32 % 10 + '0');
    }
}

void write_u64(unsigned long long vu64) // Apelaţi această funcţie pentru a scrie un număr ce se încadrează în categoria <unsigned long long>
{
    if (vu64 <= 9) {
        write_ch(vu64 + '0');
    } else {
        write_u64(vu64 / 10);
        write_ch(vu64 % 10 + '0');
    }
}

void write_appendix() // ###! ATENŢIE, Apelaţi această funcţie la finalul prgramului. Altfel, fisierul outpt NU VA CONŢINE ÎN ÎNTREGIME ceea ce doriţi!
{
    fwrite(_out_buff, 1, _out_loc, _fout);
    fclose(_fout);
}
void euler(int v,int l)
{
    VIZ[v]=1;
    nre++;
    E[nre]=v,L[nre]=l;
    if(!H[v]) H[v]=nre;
    for(int i=0;i<V[v].size();i++)
    {
        int to=V[v][i];
        if(!VIZ[to])
        {
            euler(to,l+1);
            nre++;
            E[nre]=v,L[nre]=l;
        }
    }
}
void init(int v,int l,int r)
{
    if(l==r)
        M[v]=l;
    else
    {
        init(2*v,l,(l+r)/2);
        init(2*v+1,(l+r)/2+1,r);
        if(L[M[2*v]]<=L[M[2*v+1]])
            M[v]=M[2*v];
        else
            M[v]=M[2*v+1];
    }
}
int query(int v,int st,int dr,int l,int r)
{
    if(st>r||dr<l)
        return -1;
    if(st>=l&&dr<=r)
        return M[v];
    int p1=query(2*v,st,(st+dr)/2,l,r);
    int p2=query(2*v+1,(st+dr)/2+1,dr,l,r);
    if(p1==-1)
        return p2;
    if(p2==-1)
        return p1;
    if(L[p1]<=L[p2])
        return p1;
    return p2;
}
int main()
{
    write_init();
    fi>>n>>m;
    for(int i=2;i<=n;i++)
    {
        int p;
        fi>>p;
        V[p].push_back(i);
        V[i].push_back(p);
    }
    euler(1,1);
    init(1,1,nre);
    for(int i=1;i<=m;i++)
    {
        int a,b;
        fi>>a>>b;
        write_u32(E[query(1,1,nre,min(H[a],H[b]),max(H[a],H[b]))]);
        write_ch('\n');
    }
    write_appendix();
    fi.close();
    return 0;
}