#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;
#define rep(i, n) for (int (i) = 0; (i) < (n); ++(i))
#define all(x) (x).begin(), (x).end()
#define FAST_IO ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define f first
#define s second
const int MAXN = 1e6 + 5;
int n = 1;
int last = 1;
bool pe[MAXN];
int p[MAXN];
int up[MAXN][21];
int pval[MAXN];
pair<int, int> e[MAXN];
map<pair<int, int>, int> seg;
int h[MAXN];
int realh[MAXN];
void build_up(int v) {
up[v][0] = p[v];
for (int i = 1; i < 21; ++i) {
up[v][i] = up[up[v][i - 1]][i - 1];
}
}
int get_node(int a) {
return prev(seg.upper_bound({a, 2e9}))->s;
}
int get_realh(int a) {
int v = get_node(a);
// cout << "gr " << a << " = " << realh[v] - (e[v].s - a) << endl;
return realh[v] - (e[v].s - a);
}
void init() {
// val[0] = 0;
p[0] = 0;
build_up(0);
e[0] = {0, 0};
seg[e[0]] = 0;
h[0] = 0;
realh[0] = 1;
}
void dbg() {
rep(i, n) {
cout << "node " << i << endl;
cout << "p " << p[i] << endl;
cout << "pval " << pval[i] << endl;
cout << "h " << h[i] << endl;
cout << "realh " << realh[i] << endl;
cout << "seg " << e[i].f << ' ' << e[i].s << endl;
cout << endl;
}
}
void path(int a, int s) {
a--;
int v = get_node(a);
// cout << " : " << v << endl;
if (a == e[v].s) {
// cout << "exp" << endl;
// explicit parent, no need to create extra node
pe[n] = true;
p[n] = v;
build_up(n);
pval[n] = a;
e[n] = {last, last + s - 1};
seg[e[n]] = n;
h[n] = h[v] + 1;
realh[n] = realh[v] + s;
last += s;
n++;
} else {
// cout << "imp" << endl;
// create extra node
pe[n] = false;
p[n] = p[v];
build_up(n);
pval[n] = a;
e[n] = {last, last};
seg[e[n]] = n;
h[n] = h[v];
realh[n] = get_realh(a) + 1;
last++;
n++;
a = last; // in call to path() will be decreased back
s--;
if (s > 0) {
path(a, s);
return;
}
}
// dbg();
}
int getup(int a, int x) {
// cout << "getup " << a << ' ' << x << endl;
int v = get_node(a);
int tarh = get_realh(a) - x;
// cout << get_realh(a) << endl;
// cout << v << ' ' << tarh << endl;
for (int i = 20; i >= 0; --i) {
if (realh[up[v][i]] >= tarh) {
v = up[v][i];
// cout << " -- " << i << ' ' << v << endl;
}
}
if (pe[v] || tarh == realh[v]) {
return e[v].s - (realh[v] - tarh);
} else {
return pval[v] - (realh[v] - tarh - 1);
}
// cout << " : " << v << endl;
}
int dig(int a, int b) {
// dbg();s
a--; b--;
int ac = a, bc = b;
int h1 = get_realh(ac), h2 = get_realh(bc);
if (h1 > h2) {
ac = getup(ac, h1 - h2);
} else {
bc = getup(bc, h2 - h1);
}
// cout << ac << ' ' << bc << endl;
int l = -1, r = 1e9 + 8;
while (r - l > 1) {
int m = l + (r - l) / 2;
if (getup(ac, m) == getup(bc, m)) {
r = m;
} else {
l = m;
}
}
int lca = getup(ac, r);
int lch = get_realh(lca);
int uh = get_realh(a), vh = get_realh(b);
int d = uh + vh - 2 * lch;
int da = d / 2;
if (uh >= vh) {
return getup(a, da) + 1;
} else {
return getup(b, d - da) + 1;
}
// int u0 = get_node(a), v0 = get_node(b);
// int u = u0, v = v0;
// for (int i = 20; i >= 0; --i) {
// if (h[up[u][i]] <= h[v]) {
// u = up[u][i];
// }
// }
// for (int i = 20; i >= 0; --i) {
// if (h[up[v][i]] <= h[u]) {
// v = up[v][i];
// }
// }
// if (u == v) {
// // one of nodes is parent of other
// int uh = get_realh(u), vh = get_realh(v);
// if (uh > )
// }
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
48 ms |
632 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
50 ms |
632 KB |
Output is correct |
2 |
Correct |
30 ms |
1036 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
2660 ms |
69396 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
4099 ms |
15732 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
4098 ms |
44996 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
4024 ms |
43548 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
3034 ms |
24636 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
4024 ms |
67332 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
4038 ms |
75204 KB |
Time limit exceeded |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
4101 ms |
74400 KB |
Time limit exceeded |