// compile: make data
// run: ./data < data.in
#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#ifdef LOCAL
#include <debug/codeforces.h>
#define debug(x...) _debug_print(#x, x);
#define Debug(x...) _debug_print_format(#x, x);
#else
#define debug(x...)
#define Debug(x...)
#endif
template<typename...Args> void print_(Args...args){((cout<<args<<" "),...)<<endl;}
#define VI vector<int>
#define VII vector<vector<int>>
#define VIII vector<vector<vector<int>>>
#define rep(i,a,b) for(int i=(a);i<(int)(b);++i)
#define sz(v) ((int)(v).size())
#define print(...) print_(__VA_ARGS__);
#define FIND(a, x) ((find(a.begin(),a.end(),(x))!=a.end())?1:0)
#define cmin(x,...) x=min({(x), __VA_ARGS__})
#define cmax(x,...) x=max({(x), __VA_ARGS__})
#define INTMAX (int)(9223372036854775807)
#define INF (int)(1152921504606846976)
#define NaN (int)(0x8b88e1d0595d51d1)
#define double long double
#define int long long
#define MAXN 200010
struct Tree {
int n;
vector<vector<int>> e;
struct node {
vector<node*> ch;
node* parent = nullptr;
int size, depth;
};
vector<node> vertex;
node *root;
Tree(int V) {
n = V;
e.resize(n);
vertex.resize(n);
}
void add_edge(int u, int v) {
e[u].push_back(v), e[v].push_back(u);
}
int ind(node *x) {return x - &vertex[0]; }
void build(int rt = 0) {
function<void(int, int)> dfs = [&](int u, int pre) {
vertex[u].size = 1;
vertex[u].depth = u==ind(root) ? 0 : vertex[u].parent->depth + 1;
for (int v: e[u]) {
if (v == pre) continue;
vertex[u].ch.push_back(&vertex[v]);
vertex[v].parent = &vertex[u];
dfs(v, u);
vertex[u].size += vertex[v].size;
}
};
root = &vertex[rt];
dfs(rt, -1);
}
void graphviz_dump(int plus = 0, string filename = "graph.dot") {
FILE *f = fopen(filename.c_str(), "w");
fprintf(f, "digraph Tree {\n");
rep(i, 0, n) {
node *x = &vertex[i];
fprintf(f, " %lld;\n");
}
rep(i, 0, n) {
node *x = &vertex[i];
for (auto y: x->ch) {
fprintf(f, " %ld -> %ld;\n", x - &vertex[0], y - &vertex[0]);
}
}
fprintf(f, "}\n");
}
vector<vector<int>> hp;
vector<vector<int>> ancestor() {
vector<vector<int>> p(n, vector<int>(log2(n) + 1));
rep(i, 0, n) p[i][0] = vertex[i].parent ? ind(vertex[i].parent) : -1;
rep(j, 1, log2(n)+1) rep(i, 0, n) p[i][j] = ~p[i][j-1] ? p[p[i][j-1]][j-1] : -1;
return p;
}
int lca(int u, int v) {
if (!hp.size()) hp = ancestor();
if (vertex[u].depth < vertex[v].depth) swap(u, v);
for (int k = log2(n); k >= 0; --k) if (vertex[u].depth - (1<<k) >= vertex[v].depth) u = hp[u][k];
if (u == v) return u;
for (int k = log2(n); k >= 0; --k) {
if (hp[u][k] != hp[v][k]) {
u = hp[u][k], v = hp[v][k];
}
}
return hp[u][0];
}
};
int32_t main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
int n, q; cin >> n >> q;
Tree g(n);
rep(i, 0, n-1) {
int x; cin >> x;
g.add_edge(i+1, x-1);
}
g.build(0);
// g.graphviz_dump();
// return 0;
while (q--) {
int u, v; cin >> u >> v; --u, --v;
cout << g.lca(u, v) + 1 << '\n';
}
return 0;
}
OK9casino… Last but not least. Let’s see if this stacks up well against other brands! Let’s inspect ok9casino and assess!
OK9casino… Last but not least. Let’s see if this stacks up well against other brands! Let’s inspect ok9casino and assess!
Win99? Yeah, I downloaded a few games there. Pretty slick setup. Fast downloads too! Worth trying taigamewin99.
Okay, brapublink. Sounds like a shortcut to something…interesting. Proceed with caution, folks! You’ve been warned: brapublink.
Alright, giving 80wim a whirl. Interface is pretty clean and easy to use. Nothing too flashy, but it gets the job done. They seem to have alright odds. Give it a look: 80wim.
Fancy a punt? I checked out 88phatbet and reckon it’s worth a look. Decent odds, and the interface isn’t completely rubbish. Nice one! 88phatbet
Bigdaddygamebet, eh? Had a bit of fun on there last night. Good selection of games and things to bet on. Might be back for more! bigdaddygamebet
Such a fun gaming experience. I love how they keep updating the games. If you are looking for action, ph200jili is the way to go.
Found this place through a friend and I am glad I did. Everything is professional and the customer support is actually helpful. 6733aabet
Fresh games and exciting bonuses every single day. It is hard to get bored when there is so much to explore at newjilislotgame
I love the slot selection and the bonuses for new members are generous. Such a fun way to spend the weekend at poneclubslot.
The app performance is top notch. Everything loads instantly and the graphics are crisp. It makes the whole experience so much more immersive. Check 8999vetapp out.
I’ve tried a few sites lately and this one really stands out. The interface is smooth and the payouts are fast. Definitely my new favorite spot for some action. Check out 32vin
The graphics and sound effects on this site are amazing. It feels like I am in a real casino from the comfort of my home. xx777casino is legit!
Getting into my account is always seamless. No annoying errors or long wait times. The access via dino69login is the smoothest way to get back into the action.
Finally found a site that doesn’t lag during the big games. The bonuses are generous and the registration was a breeze. br166bet7 is my new go-to spot.