Pagini recente » Cod sursa (job #166950) | Cod sursa (job #2307388) | Cod sursa (job #1917318) | Cod sursa (job #2320720) | Cod sursa (job #3228467)
/*
//trebuie sa stiu
//pozitia nodului
//nivelul nodului
//fac rmq pe sirul care este
//turul lui euler
//in dp[i][j] retin nodul de pe nivelul cel mai mic
//[i,i+2^j-1]
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
const int MAXVAL=200000,putere=17,val=100000;
int dp[MAXVAL+1][putere+1],nivel[val+1],poz[val+1],log_2[MAXVAL+1];
vector<vector<int>>gr(val+1);
vector<int>euler;
void dfs(const int& nod){
euler.push_back(nod);
poz[nod]=euler.size()-1;
for(const auto&x:gr[nod]){
nivel[x]=nivel[nod]+1;
dfs(x);
euler.push_back(nod);
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n,m,nr;
cin>>n>>m;
for(int i=2;i<=n;i++){
cin>>nr;
gr[nr].push_back(i);
}
dfs(1);
for(int i=0;i<euler.size();i++){
dp[i][0]=euler[i];
}
for(int i=2;i<=euler.size();i++){
log_2[i]=log_2[i/2]+1;
}
for(int i=euler.size()-1;i>=0;i--){
for(int j=1;i+(1<<j)-1<=euler.size()-1;j++){
if(nivel[dp[i][j-1]]<nivel[dp[i+(1<<(j-1))][j-1]]){
dp[i][j]=dp[i][j-1];
}else{
dp[i][j]=dp[i+(1<<(j-1))][j-1];
}
}
}
int a,b,l;
for(int i=1;i<=m;i++){
cin>>a>>b;
a=poz[a];
b=poz[b];
if(a>b){
swap(a,b);
}
l=log_2[b-a+1];
if(nivel[dp[a][l]]<nivel[dp[b-(1<<l)+1][l]]){
cout<<dp[a][l]<<'\n';
}else{
cout<<dp[b-(1<<l)+1][l]<<'\n';
}
}
}*/
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
//in dp[j][i] imi retin al 2^j stramos al lui i
//fac dfs ca sa determin nivelurile nodurilor
//dupa fac stramosi
//stiu tatal direct al fiecarui nod
//dp[0][i]=nr
//ma asigur ca ma aflu pe acelasi nivel
//si dupa fac algoritmul de stramosi
const int MAXVAL=1e5,putere=20;
vector<vector<int>>gr(MAXVAL+1);
int dp[putere+1][MAXVAL+1],log_2[MAXVAL+1],nivel[MAXVAL+1];
void dfs(int nod){
for(const auto&x:gr[nod]){
nivel[x]=nivel[nod]+1;
dfs(x);
}
}
int main(){
int n,m,nr;
cin>>n>>m;
for(int i=2;i<=n;i++){
cin>>nr;
gr[nr].push_back(i);
dp[0][i]=nr;
}
for(int i=2;i<=n;i++){
log_2[i]=log_2[i/2]+1;
}
for(int j=1;j<=log_2[n];j++){
for(int i=1;i<=n;i++){
dp[j][i]=dp[j-1][dp[j-1][i]];
}
}
dfs(1);
int a,b,dif;
for(int i=1;i<=m;i++){
cin>>a>>b;
if(nivel[a]>nivel[b]){
dif=nivel[a]-nivel[b];
while(dif){
a=dp[log_2[dif]][a];
dif-=1<<log_2[dif];
}
}else if(nivel[a]<nivel[b]){
dif=nivel[b]-nivel[a];
while(dif){
b=dp[log_2[dif]][b];
dif-=1<<log_2[dif];
}
}
if(a==b){
cout<<a<<'\n';
continue;
}
for(int i=log_2[nivel[a]];i>=0;i--){
if(dp[i][a]!=dp[i][b]){
a=dp[i][a];
b=dp[i][b];
}
}
cout<<dp[0][a]<<'\n';
}
}