Pagini recente » Cod sursa (job #3286715) | Clasament virtual-101 | Cod sursa (job #1970747) | Cod sursa (job #190531) | Cod sursa (job #2957591)
#include <fstream>
#include <cstring>
#include <climits>
#include <algorithm>
#include <vector>
#include <signal.h>
#define ll long long
using namespace std;
const int NMAX = 100000;
const int LGMAX = 17;
vector <int> g[NMAX + 1];
int aib[2 * NMAX + 1];
int st[NMAX + 1], dr[NMAX + 1];
int d[NMAX + 1];
int lg[NMAX + 1];
int dp[NMAX + 1][LGMAX + 1];
bool viz[NMAX + 1];
int dim;
void update(int poz, int val)
{
while (poz <= dim)
{
aib[poz] += val;
poz += poz & -poz;
}
}
int query(int val)
{
int ans = 0;
while (val)
{
ans += aib[val];
val -= val & -val;
}
return ans;
}
int aux;
void dfs(int nod)
{
viz[nod] = 1;
++aux;
st[nod] = aux;
update(aux, 0);
for (int u : g[nod])
if (!viz[u])
{
dp[u][0] = nod;
d[u] = d[nod] + 1;
dfs(u);
}
++aux;
update(aux, 0);
dr[nod] = aux;
}
void removeEdge(int a, int b)
{
if (d[a] < d[b])
swap(a, b);
update(st[a], 1);
update(dr[a], -1);
}
int lca(int a, int b)
{
if (d[a] < d[b])
swap(a, b);
int i, need = d[a] - d[b];
for (i = 0; (1 << i) <= need; i++)
if (need & (1 << i))
a = dp[a][i];
if (a == b)
return a;
int ans = 0;
for (i = lg[d[a]]; i >= 0; i--)
if (dp[a][i] == dp[b][i])
{
ans = dp[a][i];
}
else
{
a = dp[a][i];
b = dp[b][i];
}
return ans;
}
int dist(int a, int b)
{
return query(st[a]) + query(st[b]) - 2 * query(st[lca(a, b)]);
}
int main()
{
ifstream cin("disconnect.in");
ofstream cout("disconnect.out");
int n, m, i, j;
cin >> n >> m;
int v = 0;
dim = 2 * n;
for (i = 2; i <= n; i++)
{
int x;
cin >> x;
dp[i][0] = x;
g[x].push_back(i);
g[i].push_back(x);
lg[i] = lg[i / 2] + 1;
}
for (j = 1; j <= lg[n]; j++)
for (i = 1; i <= n; i++)
dp[i][j] = dp[dp[i][j - 1]][j - 1];
dfs(1);
while (m--)
{
int a, b;
cin >> a >> b;
cout << lca(a, b) << "\n";
}
}