Pagini recente » Cod sursa (job #2802602) | Cod sursa (job #3146524) | Cod sursa (job #3280162) | Cod sursa (job #373873) | Cod sursa (job #3232694)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int t[10001];
vector<int> copii[10001];
int n, m;
int pozInE[10001];
int E[10001][2];
int poz=0;
/// de fapt aici ar trebui sa avem dimensiunea aia mare de la E
/// si log2 de acea dimensiune (ca numar de coloane):
int minim[10001][21];
int minim_pos[10001][21];
void construiesteEuler(int nod, int adancime)
{
if (pozInE[nod]==0) pozInE[nod]=poz;
E[poz][0] = nod;
E[poz][1] = adancime;
poz++;
for(auto y : copii[nod])
{
construiesteEuler(y, adancime+1);
E[poz][0] = nod;
E[poz][1] = adancime;
poz++;
}
}
int minimInterval(int s, int d){
if (s==d) return minim[s][0];
int k=0;
while((1<<k)+s<=d) k++;
k--;
if (s+(1<<k)<d) return min(minim[s][k],minimInterval(s+(1<<k),d));
else return minim[s][k+1];
}
int pozMinim(int s, int d){
int k=0;
while((1<<k)+s<=d) k++;
k--;
if (s+(1<<k)<d) return (minim[s][k]<minimInterval(s+(1<<k),d)?minim_pos[s][k]:pozMinim(s+(1<<k),d));
else return minim_pos[s][k+1];
}
int main()
{
fin >> n >> m;
for(int i=2; i<=n; i++)
{
fin >> t[i];
copii[t[i]].push_back(i);
}
/*for(int i=1; i<=n; i++)
{
fout << i << ' ';
for(auto y : copii[i])
fout << y << ' ';
fout << '\n';
}
*/
construiesteEuler(1,0); /// aici poti pune "tatal"
for(int i=0; i<poz; i++)
{
minim[i][0]=E[i][1];
minim_pos[i][0]=i;
}
for(int k=1; k<8; k++)
{
for(int i=0; i<poz-(1<<(k-1)); i++)
{
minim[i][k] = min(minim[i][k-1],minim[i+(1<<(k-1))][k-1]);
minim_pos[i][k] = (minim[i][k-1] <= minim[i+(1<<(k-1))][k-1] ? minim_pos[i][k-1] : minim_pos[i+(1<<(k-1))][k-1]);
}
}
for(int interval=0; interval<m; interval++)
{
int x,y;
fin >> x >> y;
if (pozInE[x]>pozInE[y]) swap(x,y);
//fout << E[pozMinim(pozInE[x], pozInE[y])-1][0] << endl;
//fout << pozMinim(pozInE[x], pozInE[y]) << endl;
//fout << x << " este in pozitia " << pozInE[x] << endl;
//fout << y << " este in pozitia " << pozInE[y] << endl;
//fout << "intre " << pozInE[x] << " si " << pozInE[y] << " minimul este " << minimInterval(pozInE[x],pozInE[y]) << " si e pe pozitia " << pozMinim(pozInE[x],pozInE[y]) << endl;
fout << E[pozMinim(pozInE[x],pozInE[y])][0] << endl;
}
//fout << endl;
// for(int i=0; i<30; i++)
// {
// for(int j=0; j<8; j++)
// cout << minim[i][j] << '['<< (minim_pos[i][j]<10?" ":"")<< minim_pos[i][j] <<']'<< " ";
// cout << endl;
// }
//
// for(int i=0; i<poz; i++)
// fout <<i << " - "<< E[i][0] << ' ' << E[i][1] << endl;
//for(int i=0; i<poz; i++)
// fout << E[i][1] << endl;
return 0;
}