Pagini recente » Cod sursa (job #3360575) | Cod sursa (job #3360570) | Cod sursa (job #3360568) | Cod sursa (job #3360567)
/**
//met I, cu AIB
#include <iostream>
#include <fstream>
#include <vector>
#include <bitset>
using namespace std;
const int N=1e5+5,M=18;
int n,m,pc;
int t[N];
int p_start[N],p_end[N];
int stramos[N][M];
bitset<N> viz;
vector<int> g[N];
bool este_stramos(int x,int y)
{
return p_start[x]<=p_start[y] and p_end[y]<=p_end[x];
}
void dfs(int nod)
{
viz[nod]=1;
p_start[nod]=pc++;
for(auto el:g[nod])
if(!viz[el])
dfs(el);
p_end[nod]=pc++;
}
int lca(int a, int b)
{
if(este_stramos(a,b))return a;
if(este_stramos(b,a))return b;
for(int p=M-1; p>=0; p--)
{
int c=stramos[a][p];
if(c and !este_stramos(c,b))
{
a=c;
}
}
return stramos[a][0];
}
void generare_stramosi()
{
int i(1);
for(; i<=n; i++)stramos[i][0]=t[i];
for(int p(1); p<M; p++)
{
for(int nod=1; nod<=n; nod++)
stramos[nod][p]=
stramos[stramos[nod][p-1]][p-1];
}
}
int main()
{
ifstream fin("lca.in");
fin>>n>>m;
int i(2),j;
for(; i<=n; i++)
{
fin>>t[i];
g[t[i]].push_back(i);
}
dfs(1);
generare_stramosi();
ofstream fout("lca.out");
while(m--)
{
fin>>i>>j;
fout<<lca(i,j)<<'\n';
}
fin.close();
fout.close();
return 0;
}
*/
#include <iostream>
#include <fstream>
#include <vector>
#include <bitset>
#include <iomanip>
using namespace std;
struct Lucriri_pt_RMQ
{
int nod,niv;
};
const int N=1e5+5,M=18;
int n,m,cnt;
int t[N];
int p_start[2*N],logaritm[2*N];
Lucriri_pt_RMQ rmq[N*2][M];
bitset<N> viz;
vector<int> g[N];
void dfs(int nod,int niv)
{
viz[nod]=1;
p_start[nod]=++cnt;
rmq[cnt][0]= {nod,niv};
for(auto el:g[nod])
if(!viz[el])
{
dfs(el,niv+1);
rmq[++cnt][0]= {nod,niv};
}
}
int lca(int a, int b)
{
int pa=p_start[a],pb=p_start[b];
if(pa>pb)swap(pa,pb);
if(rmq[pa][logaritm[pb-pa+1]].niv<
rmq[pb-(1<<(logaritm[pb-pa+1]))+1][(logaritm[pb-pa+1])].niv)
return rmq[pa][(logaritm[pb-pa+1])].nod;
return rmq[pb-(1<<(logaritm[pb-pa+1]))+1][(logaritm[pb-pa+1])].nod;
}
void generare_rmq()
{
for(int p(1); p<M; p++)
{
for(int nod=1; nod<=cnt; nod++)
{
rmq[nod][p]=rmq[nod][p-1];
if(nod+(1<<(p-1))<=cnt&&
rmq[nod][p].niv>rmq[nod+(1<<(p-1))][p-1].niv)
rmq[nod][p]=rmq[nod+(1<<(p-1))][p-1];
}
}
}
void generare_logaritmi()
{
for(int i(2); i<=cnt; ++i)logaritm[i]=1+logaritm[i/2];
}
int main()
{
ifstream fin("lca.in");
fin>>n>>m;
int i(2),j;
for(; i<=n; i++)
{
fin>>t[i];
g[t[i]].push_back(i);
}
dfs(1,1);
generare_rmq();
generare_logaritmi();
ofstream fout("lca.out");
while(m--)
{
fin>>i>>j;
fout<<lca(i,j)<<'\n';
}
fin.close();
fout.close();
for(j=0; j<M; j++,cout<<'\n')
for(i=1; i<=cnt; i++)
{
cout<<setw(3)<<rmq[i][j].niv<<' ';
}
return 0;
}