Pagini recente » Cod sursa (job #2584668) | Cod sursa (job #1273439) | Cod sursa (job #2389505) | Cod sursa (job #787720) | Cod sursa (job #2426170)
#include <iostream>
#include <fstream>
#include <vector>
#include <deque>
#include <set>
#include <map>
#include <unordered_map>
#include <list>
#include <array>
#include <cstdlib>
#include <stack>
#include <string>
#include <queue>
#include <chrono>
#include <functional>
#include <limits>
#include <cmath>
#include <algorithm>
#include <random>
#include <regex>
#include <tuple>
#include <utility>
#include <bitset>
#include <complex>
#include <iomanip>
#include <ostream>
#include <sstream>
#include <ctime>
#include <cassert>
using namespace std;
#define for0(i, n) for(int i = 0; i < n; i++)
#define for1(i, n) for(int i = 1; i <= n; i++)
#define pb push_back
#define mp make_pair
#define all(v) v.begin(), v.end()
#define V vector<int>
#define VP vector<pair<int, int> >
#define FASTIO ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define index INDEX
#ifndef ONLINE_JUDGE
#define print(x) PRINT(x, #x)
template<typename T> inline const void PRINT(T VARIABLE, const string& NAME) {
cerr << NAME << " = " << fixed << VARIABLE << "\n";
}
#else
#define print(x) 0
#endif
#ifdef RAND_MAX
#undef RAND_MAX
#endif
#define RAND_MAX 999999937
int generate_random() {
const int MAX_RANDOM = (int)1e6;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
return uniform_int_distribution<int>(0, MAX_RANDOM)(rng);
}
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const ll INFLL = 2 * (ll)1e18 + 100;
//#define int ll
#ifdef int
const int INFINT = INFLL;
#else
const int INFINT = 2 * (int)1e9 + 100;
#endif
const double PI = atan(1) * 4;
const double EPS = 1e-6;
const int SEED = (int)1e3 + 7;
const int MOD = (int)1e9 + 7;
const int NMAX = (int)1e5 + 5;
const int BMAX = 20;
int n, m;
V tree[NMAX];
int depth[NMAX];
int parent[NMAX][BMAX];
void dfs(int nod, int p, int d = 1) // NOTE: have to start from 1
{
depth[nod] = d;
parent[nod][0] = p;
for(int j = 1; j < BMAX; j++)
{
parent[nod][j] = parent[parent[nod][j - 1]][j - 1];
}
for(auto i: tree[nod]) if(i != p)
{
dfs(i, nod, d + 1);
}
}
int lca(int l, int r)
{
if (depth[l] < depth[r]) swap(l, r);
for (int i = BMAX - 1; i >= 0; i--) if (depth[parent[l][i]] >= depth[r]) l = parent[l][i];
if (l == r) return l;
for(int i = BMAX - 1; i >= 0; i--)
{
if(parent[l][i] != parent[r][i])
{
l = parent[l][i];
r = parent[r][i];
}
}
return parent[l][0];
}
int32_t main() {
#ifndef ONLINE_JUDGE
double START_PROGRAM = clock();
#endif
srand(time(0));
cout << setprecision(20) << fixed;
FASTIO;
ifstream cin("lca.in");
ofstream cout("lca.out");
cin >> n >> m;
for(int i = 2; i <= n; i++)
{
int p;
cin >> p;
tree[i].pb(p);
tree[p].pb(i);
}
dfs(1, 0, 1);
while(m--)
{
int a, b;
cin >> a >> b;
cout << lca(a, b) << '\n';
}
#ifndef ONLINE_JUDGE
double END_PROGRAM = clock();
double ELAPSED_TIME = (END_PROGRAM - START_PROGRAM) / CLOCKS_PER_SEC;
cerr << "\n\nElapsed Time: " << ELAPSED_TIME * 1000 << "\n";
#endif
return 0;
}