Pagini recente » Cod sursa (job #2591435) | Cod sursa (job #2775987) | Cod sursa (job #1016653) | Cod sursa (job #60997) | Cod sursa (job #1947486)
#include <bits/stdc++.h>
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 (;'0'<=buffer[index] and buffer[index]<='9';inc())
n=10*n+buffer[index]-'0';
return *this;}
~parser(){
input_file.close();}
private:
fstream input_file;
static const int SIZE=0x200000;
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;
int index=0,aux,n;
char buffer[SIZE],nr[24];
inline void inc(){
if(++index==SIZE)
index=0,output_file.write(buffer,SIZE);}
};
parser fin("lca.in");
writer fout("lca.out");
const int N = 1e5 + 1;
const int D = 18;
vector <int> edges[N], eulerChart;
bitset <N> visited;
int totalNodes, totalQuestions, length[D], depth;
int level[N], position[N];
int rangeMinimumQuery[2][D][3*N];
inline void readVariables(){
fin >> totalNodes >> totalQuestions;
int origin;
for ( int index = 2; index <= totalNodes; index++ ){
fin >> origin;
edges[origin].push_back(index);
edges[index].push_back(origin);
}
}
void DFS(int node = 1){
visited[node] = true;
eulerChart.push_back(node);
position[node] = eulerChart.size();
for ( auto it : edges[node] ){
if ( !visited[it] ){
level[it] = level[node] + 1;
DFS(it);
eulerChart.push_back(node);
}
}
}
inline void RMQ(){
length[0] = eulerChart.size();
depth = (int)(log2(length[0]));
for ( int index = 1; index <= length[0]; index++ ){
rangeMinimumQuery[0][0][index] = level[eulerChart[index-1]];
rangeMinimumQuery[1][0][index] = eulerChart[index-1];
}
for ( int index = 1; index <= depth; index++ )
length[index] = length[index-1] - (1<<(index-1));
for ( int indexY = 1; indexY <= depth; indexY++ ){
for ( int indexX = 1; indexX <= length[indexY]; indexX++ ){
if (rangeMinimumQuery[0][indexY-1][indexX] < rangeMinimumQuery[0][indexY-1][indexX + (1<<(indexY-1))] ){
rangeMinimumQuery[0][indexY][indexX] = rangeMinimumQuery[0][indexY-1][indexX];
rangeMinimumQuery[1][indexY][indexX] = rangeMinimumQuery[1][indexY-1][indexX];
}
else{
rangeMinimumQuery[0][indexY][indexX] = rangeMinimumQuery[0][indexY-1][indexX + (1<<(indexY-1))];
rangeMinimumQuery[1][indexY][indexX] = rangeMinimumQuery[1][indexY-1][indexX + (1<<(indexY-1))];
}
}
}
}
inline void readQuestions(){
int first, second;
for ( ; totalQuestions; totalQuestions-- ){
fin >> first >> second;
first = position[first];
second = position[second];
if ( first > second )
swap(first, second);
int lengthPeriod = second - first + 1;
int maxPeriod = 1 << ( (int) (log2(lengthPeriod)) );
int indexY = log2(maxPeriod);
if ( rangeMinimumQuery[0][indexY][first] < rangeMinimumQuery[0][indexY][second-(1<<indexY)+1] )
fout << rangeMinimumQuery[1][indexY][first] << "\n";
else
fout << rangeMinimumQuery[1][indexY][second-(1<<indexY)+1] << "\n";
}
}
int main(){
readVariables();
DFS();
RMQ();
readQuestions();
}