Pagini recente » Cod sursa (job #837113) | Cod sursa (job #2219605) | Cod sursa (job #908790) | Cod sursa (job #1695296) | Cod sursa (job #2397907)
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
class parser{
public:
parser() {}
parser(const char *file_name){
input_file.open(file_name,ios::in | ios::binary);
input_file.sync_with_stdio(false);
index=0;
input_file.read(buffer,SIZE);}
inline parser &operator >>(int &n) {
for (;buffer[index]<'0' or buffer[index] > '9'; inc());
n &= 0;
for (; buffer[index] >= '0' and buffer[index] <= '9'; inc())
n = (n << 3) + (n << 1) + buffer[index] - '0';
return *this;
}
inline parser &operator >>(char n[]){
for (;buffer[index]<'0' or buffer[index]>'z';inc());
int it=0;
for (;'0'<=buffer[index] and buffer[index]<='z';inc())
n[it++]=buffer[index];
n[it]='\0';
return *this;}
~parser(){
input_file.close();}
private:
fstream input_file;
static const int SIZE=0x400000;
char buffer[SIZE];
int index=0;
inline void inc(){
if(++index==SIZE)
index=0,input_file.read(buffer,SIZE);}
};
class writer{
public:
writer() {};
writer(const char *file_name){
output_file.open(file_name,ios::out | ios::binary);
output_file.sync_with_stdio(false);
index&=0;}
inline writer &operator <<(int target){
aux&=0;
n=target;
if (!n)
nr[aux++]='0';
for (;n;n/=10)
nr[aux++]=n%10+'0';
for(;aux;inc())
buffer[index]=nr[--aux];
return *this;}
inline writer &operator <<(const char *target){
aux&=0;
while (target[aux])
buffer[index]=target[aux++],inc();
return *this;}
~writer(){
output_file.write(buffer,index);output_file.close();}
private:
fstream output_file;
static const int SIZE=0x200000; ///2MB
int index,aux,n;
char buffer[SIZE],nr[24];
inline void inc(){
if(++index==SIZE)
index&=0,output_file.write(buffer,SIZE);}
};
parser f("lca.in");
writer t("lca.out");
using namespace std;
/*
ifstream f ("lca.in");
ofstream t ("lca.out");
*/
vector <int> groups;
int n, m, depth[100010], grup[100010], tata[100010];
void preprocess() {
int bucket_size = sqrt(n / 2);
for (int i = 1; i <= n; ++i) {
if (depth[i] % bucket_size == 0) {
groups.push_back(tata[i]);
grup[i] = groups.size() - 1;
} else {
grup[i] = grup[tata[i]];
}
}
}
int H_BFS(int x, int y) {
while (x != y)
if (depth[x] > depth[y])
x = tata[x];
else
y = tata[y];
return x;
}
int lca(int x, int y) {
while (grup[x] != grup[y])
if (depth[x] > depth[y])
x = groups[grup[x]];
else
y = groups[grup[y]];
return H_BFS(x, y);
}
int main()
{
f >> n >> m;
for (int x, i = 2; i <= n; ++i)
f >> x,
tata[i] = x,
depth[i] = depth[x] + 1;
preprocess();
for (int x, y, i = 0; i < m; ++i)
f >> x >> y,
t << lca(x, y) << "\n";
return 0;
}