Pagini recente » Cod sursa (job #1107868) | Cod sursa (job #2554772) | Cod sursa (job #1372580) | Cod sursa (job #948226) | Cod sursa (job #2315244)
#include <iostream>
#include <fstream>
#include <vector>
#include <stdio.h>
#include <ctype.h>
using namespace std;
class InParser {
private:
FILE *fin;
char *buff;
int sp;
char read_ch() {
++sp;
if (sp == 4096) {
sp = 0;
fread(buff, 1, 4096, fin);
}
return buff[sp];
}
public:
InParser(const char* nume) {
fin = fopen(nume, "r");
buff = new char[4096]();
sp = 4095;
}
InParser& operator >> (int &n) {
char c;
while (!isdigit(c = read_ch()) && c != '-');
int sgn = 1;
if (c == '-') {
n = 0;
sgn = -1;
} else {
n = c - '0';
}
while (isdigit(c = read_ch())) {
n = 10 * n + c - '0';
}
n *= sgn;
return *this;
}
InParser& operator >> (long long &n) {
char c;
n = 0;
while (!isdigit(c = read_ch()) && c != '-');
long long sgn = 1;
if (c == '-') {
n = 0;
sgn = -1;
} else {
n = c - '0';
}
while (isdigit(c = read_ch())) {
n = 10 * n + c - '0';
}
n *= sgn;
return *this;
}
};
int k,p;
ofstream fo("lca.out");
vector <int> D[100001];
int n,q;
int ne,E[300001];
int FIRST[100001];
int LEVEL[100001];
int T[300001][20];
int query(int st, int dr)
/// returneaza varful de nivel minim care apare
/// intre E[st] si E[dr];
{
if (st>dr)
swap(st,dr);
int rez;
rez=E[st];
for (int i=k;i>=0;i--)
if (st+(1<<i)-1<=dr)
{
if (LEVEL[rez]>LEVEL[T[st][i]])
rez=T[st][i];
st=st+(1<<i);
}
return rez;
}
void lvl(int nod,int level)
{
LEVEL[nod]=level;
vector <int> :: iterator it;
for (it=D[nod].begin(); it!=D[nod].end(); it++)
lvl(*it,level+1);
}
void euler(int nod)
{
vector <int> :: iterator it;
if (D[nod].size()==0)
{
ne++;
E[ne]=nod;
if(FIRST[nod]==0)
FIRST[nod]=ne;
}
else
{
ne++;
E[ne]=nod;
if(FIRST[nod]==0)
FIRST[nod]=ne;
for (it=D[nod].begin(); it!=D[nod].end(); it++)
{
euler(*it);
ne++;
E[ne]=nod;
if(FIRST[nod]==0)
FIRST[nod]=ne;
}
}
}
int main()
{
InParser fi("file.in");
fi>>n>>q;
for(int i=2; i<=n; i++)
{
int a;
fi>>a;
D[a].push_back(i);
}
euler(1);
lvl(1,0);
/// se construieste sparse table pentru E
/// k este indicele ultimei coloane din T
k=0;
p=1;
while (p*2<=ne)
{
k++;
p=p*2;
}
/// se construieste sparse table
for (int i=1; i<=ne; i++)
T[i][0]=E[i];
for (int j=1; j<=k; j++)
for (int i=1; i<=ne-(1<<j)+1; i++)
if (LEVEL[T[i][j-1]]<LEVEL[T[i+(1<<(j-1))][j-1]])
T[i][j]=T[i][j-1];
else
T[i][j]=T[i+(1<<(j-1))][j-1];
/// se raspunde la intrebari
for (int qu=1; qu<=q; qu++)
{
int a,b;
fi>>a>>b;
fo<<query(FIRST[a],FIRST[b])<<"\n";
}
fo.close();
return 0;
}