#include <bits/stdc++.h>
using namespace std;
int depth(int x) {
if ((int)(pow(8*x+1, 0.5)+1)/2 == (pow(8*x+1, 0.5)+1)/2) return (pow(8*x+1, 0.5)+1)/2-1;
else return (int)(pow(8*x+1, 0.5)+1)/2;
}
//time to deal with binary lifting :(
signed main() {
int n; cin >> n;
int q; cin >> q;
int t; cin >> t;
int a[n+1];
for (int i = 1; i < n+1; i++) {
int x; cin >> x;
a[i] = x-((i-1)*i)/2;
}
pair<int,int> par[n+2][n+2][15]; for (int i = 0; i < n+2; i++) for (int j = 0; j < n+2; j++) par[i][j][0] = {0,0};
for (int i = 2; i < n+2; i++) {
for (int j = 1; j <= i; j++) {
if (j > a[i-1]) par[i][j][0] = {i-1, j-1};
else par[i][j][0] = {i-1,j};
}
}
for (int i = 1; i < 15; i++) {
for (int j = 2; j < n+2; j++) {
for (int k = 1; k <= j; k++) {
par[j][k][i] = par[par[j][k][i-1].first][par[j][k][i-1].second][i-1];
}
}
}
while (q--) {
int x, y; cin >> x >> y;
//first check for depth
if (y > x) swap(x, y);
pair<int,int> cox, coy;
cox = {depth(x), x-((depth(x)-1)*depth(x))/2};
coy = {depth(y), y-((depth(y)-1)*depth(y))/2};
int tmp = depth(x)-depth(y);
//now lift x until its the same depth :)
for (int i = 14; i >= 0; i--) {
if ((tmp&(1<<i)) > 0) cox = par[cox.first][cox.second][i];
}
//now they are the same depth. now we can do some lca :)
if (cox == coy) {
cout << ((cox.first-1)*cox.first)/2+cox.second << '\n';
}
else {
for (int i = 14; i >= 0; i--) {
auto tmp1 = par[cox.first][cox.second][i];
auto tmp2 = par[coy.first][coy.second][i];
if (tmp1.first != tmp2.first or tmp1.second != tmp2.second) {
cox = tmp1;
coy = tmp2;
}
}
cox = par[cox.first][cox.second][0];
cout << ((cox.first-1)*cox.first)/2+cox.second << '\n';
}
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |