Cod sursa(job #3349137)

Utilizator comanandreiComan Andrei comanandrei Data 25 martie 2026 17:27:46
Problema Lowest Common Ancestor Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.03 kb
#include <stdio.h>

#define MAXN 100000
#define MAXQ 2000000

using namespace std;

FILE *fin, *fout;

struct cell{
    int v, next;
};

struct node{
    int adj;
    int depth;
    int time_in, time_out;
    int parent;
    int jump;
};

struct query{
    int u, v;
};

cell edges[2*MAXN];
node nd[MAXN+1];
query queries[MAXQ];
int n, q;

void dfs(int u){
    static int time=1;
    nd[u].time_in=time++;
    int u2=nd[u].jump, u3=nd[u2].jump;
    bool egal=false;
    if(nd[u2].depth-nd[u].depth==nd[u3].depth-nd[u].depth){
        egal=true;
    }
    for(int ptr=nd[u].adj;ptr;ptr=edges[ptr].next){
        int v=edges[ptr].v;
        if(!nd[v].depth){
            nd[v].depth=nd[u].depth+1;
            nd[v].parent=u;
            if(egal){
                nd[v].jump=u3;
            }
            else{
                nd[v].jump=u;
            }
            dfs(v);
        }
    }
    nd[u].time_out=time++;
}

bool is_ancestor(int u, int v){
    return (nd[u].time_in<=nd[v].time_in)&&
           (nd[u].time_out>=nd[v].time_out);
}

int lca(int u, int v){
    while(!is_ancestor(u, v)){
        if(nd[u].jump&&!is_ancestor(nd[u].jump, v)){
            u=nd[u].jump;
        }
        else{
            u=nd[u].parent;
        }
    }
    return u;
}

void add_edge(int u, int v){
    static int pos=1;
    edges[pos]={v, nd[u].adj};
    nd[u].adj=pos++;
}

void read_graph_and_queries(){
    int u;
    fin=fopen("lca.in", "r");
    fscanf(fin, "%d%d", &n, &q);
    for(int i=2;i<=n;i++){
        fscanf(fin, "%d", &u);
        add_edge(i, u);
        add_edge(u, i);
    }
    for(int i=0;i<q;i++){
        fscanf(fin, "%d%d", &queries[i].u, &queries[i].v);
    }
    fclose(fin);
}

void ans_queries(){
    fout=fopen("lca.out", "w");
    for(int i=0;i<q;i++){
        fprintf(fout, "%d\n", lca(queries[i].u, queries[i].v));
    }
    fclose(fout);
}

int main()
{
    read_graph_and_queries();
    nd[1].depth=1;
    dfs(1);
    ans_queries();
    return 0;
}