Pagini recente » Cod sursa (job #1724852) | Cod sursa (job #1316879) | Cod sursa (job #2461698) | Cod sursa (job #35079) | Cod sursa (job #2910564)
#include<bits/stdc++.h>
using namespace std;
class input {
private:
FILE* fin;
char* t;
int sp;
const int sz = 10000;
char read()
{
if (sp == sz)
{
fread(t, 1, sz, fin);
sp = 0;
return t[sp++];
}
else
return t[sp++];
}
public:
input(const char* name)
{
fin = fopen(name, "r");
sp = sz;
t = new char[sz]();
}
void close()
{
fclose(fin);
}
void open(const char* name)
{
fin = fopen(name, "r");
sp = sz;
t = new char[sz]();
}
input& operator >> (int& n)
{
char c = read();
while (c == ' ' || c == '\n')
c = read();
n = 0;
int sng = 1;
if (c == '-')
sng = -1, c = read();
while (c != '\0' && isdigit(c))
n = n * 10 + (c - '0'), c = read();
n *= sng;
return *this;
}
input& operator >> (char& s)
{
char c = read();
while (c != '\0' && c == '\n')
c = read();
s = c;
return *this;
}
input& operator >> (long long& n)
{
char c = read();
while (c == ' ' || c == '\n')
c = read();
n = 0;
int sng = 1;
if (c == '-')
sng = -1, c = read();
while (c != '\0' && isdigit(c))
n = n * 10 + (c - '0'), c = read();
n *= sng;
return *this;
}
void getline(string& s)
{
char c = read();
s = "";
while (c != '\0' && c != '\n')
s += c, c = read();
}
input& operator >> (string& s)
{
char c;
c = read();
s = "";
while (c == '\n' || c == ' ')
c = read();
while (c != '\n' && c != '\0' && c != ' ')
s += c, c = read();
return *this;
}
input& operator >> (char* s)
{
char c;
c = read();
int i = 0;
while (c == '\n' || c == ' ')
c = read();
while (c != '\n' && c != '\0' && c != ' ')
s[i++] = c, c = read();
return *this;
}
};
class output {
private:
FILE* fout;
char* t;
int sp;
const int sz = 10000;
void write(char c)
{
if (sp == sz)
{
fwrite(t, 1, sz, fout);
sp = 0;
t[sp++] = c;
}
else
t[sp++] = c;
}
public:
output(const char* name)
{
fout = fopen(name, "w");
sp = 0;
t = new char[sz]();
}
~output()
{
fwrite(t, 1, sp, fout);
}
output& operator << (int n)
{
if (n < 0)
{
write('-');
n *= -1;
}
if (n <= 9)
write(char(n + '0'));
else
{
(*this) << (n / 10);
write(char(n % 10 + '0'));
}
return *this;
}
output& operator << (char c)
{
write(c);
return *this;
}
output& operator << (const char* s)
{
int i = 0;
while (s[i] != '\0')
write(s[i++]);
return *this;
}
output& operator << (long long n)
{
if (n < 0)
{
write('-');
n *= -1;
}
if (n < 10)
write(char(n + '0'));
else
{
(*this) << (n / 10);
write(char(n % 10 + '0'));
}
return *this;
}
output& operator << (string s)
{
for (auto i : s)
write(i);
return *this;
}
void precizion(double x, int nr)
{
int p = floor(x);
*this << p;
if (nr == 0)
return;
write('.');
for (int i = 1; i <= nr; i++)
{
x -= floor(x);
x *= 10;
write(int(x) + '0');
}
}
};
input fin("lca.in");
output fout("lca.out");
int v[500001], n, q, k, first[100001];
vector<vector<int>> rmq((500001), vector<int>(20));
vector<vector<int>> g(100001);
void dfs(int nod)
{
v[++k] = nod;
first[nod] = k;
for (auto i : g[nod])
{
dfs(i);
v[++k] = nod;
}
}
void RMQ()
{
for (int i = 1; i <= k; i++)
rmq[i][0] = v[i];
for (int j = 1; (1 << j) <= k; j++)
for (int i = 1; i + (1 << j) - 1 <= k; i++)
rmq[i][j] = min(rmq[i][j - 1], rmq[i + (1 << (j - 1))][j - 1]);
}
int minim(int l, int r)
{
int j = log2(r - l + 1);
return min(rmq[l][j], rmq[r - (1 << j) + 1][j]);
}
int main()
{
fin >> n >> q;
for (int i = 2; i <= n; i++)
{
int x;
fin >> x;
g[x].push_back(i);
}
dfs(1);
RMQ();
for(int i = 1; i <= q; i++)
{
int x, y;
fin >> x >> y;
fout << minim(min(first[x], first[y]), max(first[x], first[y])) << '\n';
}
return 0;
}