QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#751728 | #8547. Whose Land? | 000226 | RE | 0ms | 16912kb | C++17 | 5.3kb | 2024-11-15 20:19:41 | 2024-11-15 20:19:42 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define lep(i, l, r) for(int i = (l); i <= (r); i ++)
#define rep(i, l, r) for(int i = (l); i >= (r); i --)
const int P = 998244353;
inline int mod(int x) { return x + (x >> 31 & P);}
inline void pls(int &x, int y) { x = mod(x + y - P); }
inline void sub(int &x, int y) { x = mod(x - y); }
int power (int x, int k) {
int res = 1;
while (k) {
if (k & 1) res = 1ll * res * x % P;
x = 1ll * x * x % P; k >>= 1;
} return res;
}
using i64 = long long;
const int N = 1e5 + 5;
int n, k, q;
vector<int> e[N];
int bfn[N], loc[N], fa[N];
struct Odt {
struct node {
int l;
mutable int val;
inline bool operator <(const node &rhs) const {
return l < rhs.l;
}
} ;
set<node> st;
void clear() {
st.clear();
st.insert ({1, 0});
}
void split(int pos) {
if (pos > n) return ;
auto it = st.upper_bound ({pos, 0});
-- it;
assert (it -> l <= pos);
if (it -> l == pos) return ;
st.insert({pos, it -> val});
}
void modify (int l, int r, int v, vector<tuple<int, int, int> > & rec) {
split (l);
split (r + 1);
auto itl = st.lower_bound({l, 0});
auto itr = st.lower_bound({r + 1, 0});
rec.clear();
for (auto it = itl; it != itr; ++ it) {
int r = n;
if (next(it) != st.end())
r = next(it) -> l - 1;
rec.push_back ({it -> l, r, it -> val});
}
st.erase(itl, itr);
st.insert({l, v});
}
} odt;
void bfs() {
int tot = 0;
queue<int> q;
q.push (1);
while (q.size()) {
int x = q.front(); q.pop();
bfn[++ tot] = x;
loc[x] = tot;
for (int y : e[x]) if (y != fa[x]) {
fa[y] = x;
q.push (y);
}
}
}
struct bit {
#define lowbit(x) (x & -x)
int c[N];
void upd(int x, int y) {
for (; x; x -= lowbit(x)) c[x] += y;
}
int qry (int x) {
int ans = 0;
for (; x <= n; x += lowbit(x))
ans += c[x];
return ans;
}
void clear() {
for (int i = 1; i <= n; i ++) c[i] = 0;
}
} bt;
vector<pair<int, int> > linkqry[N];
int finalans[N * 5];
int sz[N], dfn[N];
int mnbfn[N], mxbfn[N];
int st[20][N], lg[N], dep[N];
void dfs (int x, int fx) {
sz[x] = 1;
dfn[x] = ++ dfn[0];
st[0][dfn[0]] = fx;
dep[x] = dep[fx] + 1;
//cerr << x << " " << dep[x] << endl;
for (int y : e[x])
if (y != fx)
dfs (y, x),
sz[x] += sz[y];
}
int updst (int x, int y) {
return dep[x] < dep[y] ? x : y;
}
inline int lca(int x, int y) {
if (x == y) return x;
x = dfn[x];
y = dfn[y];
if (x > y) swap (x, y);
int d = log2(y - x ++);
return updst (st[d][x], st[d][y - (1 << d) + 1]);
}
inline int dist(int x, int y) {
int lc = lca (x, y);
return dep[x] + dep[y] - dep[lc] * 2;
}
void solve() {
cin >> n >> k >> q;
lep (i, 2, n) lg[i] = lg[i >> 1] + 1;
lep (i, 1, n) e[i].clear(), fa[i] = 0;
lep (i, 2, n) {
int x, y;
cin >> x >> y;
e[x].push_back (y);
e[y].push_back (x);
}
dfn[0] = 0;
bfs ();
dfs (1, 0);
odt.clear();
lep (i, 1, lg[n] + 1)
for (int j = 1; j + (1 << i) - 1 <= n; j ++)
st[i][j] = updst (st[i - 1][j], st[i - 1][j + (1 << (i - 1))]);
lep (i, 1, n) linkqry[i].clear();
lep (i, 1, q) {
int l, r;
cin >> l >> r;
linkqry[r].push_back ({l, i});
}
lep (i, 1, n) mnbfn[i] = n, mxbfn[i] = 1;
lep (i, 1, n) {
mnbfn[dep[i]] = min(mnbfn[dep[i]], bfn[i]);
mxbfn[dep[i]] = max(mxbfn[dep[i]], bfn[i]);
}
bt.clear();
auto add = [&] (int x) -> void {
for (int nowdep = dep[x] - k; nowdep <= dep[x] + k; ++ nowdep) {
if (nowdep <= 0) continue;
//cerr << nowdep << endl;
//cerr << dep[x] - k << ' ' << dep[x] + k << endl;
//cerr << x << ' ' << dep[x] << endl;
int L = mnbfn[nowdep];
int R = mxbfn[nowdep];
int find_a_node = 0;
if (nowdep >= dep[x]) {
auto it = lower_bound(bfn + L, bfn + R + 1, x, [&](int a, int b) {
return dfn[a] < dfn[b];
} );
if (it > bfn + R) ;
else {
// [L, R]
if (dist(* it, x) <= k)
find_a_node = * it;
}
if (! find_a_node) {
-- it;
if (it >= bfn + L) {
if (dist (*it, x) <= k)
find_a_node = * it;
}
}
}
else {
int tmp = x;
while (dep[tmp] != nowdep)
tmp = fa[tmp];
find_a_node = tmp;
}
if (find_a_node == 0) continue;
int now_id = bfn[find_a_node];
int okl = now_id, okr = now_id;
int l = L, r = now_id, res = now_id;
while (l <= r) {
int mid = (l + r) >> 1;
if (dist(bfn[mid], x) <= k)
r = mid - 1, res = mid;
else
l = mid + 1;
}
okl = res;
l = now_id, r = R, res = now_id;
while (l <= r) {
int mid = (l + r) >> 1;
if (dist(bfn[mid], x) <= k)
l = mid + 1, res = mid;
else
r = mid - 1;
}
okr = res;
assert (okl <= okr);
// [okl, okr]
vector<tuple<int, int, int> > seq;
odt.modify(okl, okr, x, seq);
for (auto [ll, rr, v] : seq) {
bt.upd (v, - (rr - ll + 1) );
}
bt.upd (x, okr - okl + 1);
}
} ;
//add (2);
//return ;
lep (r, 1, n) {
add(r);
for (auto [l, id] : linkqry[r]) {
finalans[id] = bt.qry (l);
}
}
lep (i, 1, q) cout << finalans[i] << '\n';
}
int main() {
ios :: sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int Case = 1;
cin >> Case;
while (Case --) solve();
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 16912kb
input:
2 5 1 2 1 2 1 3 2 4 2 5 2 2 2 3 8 2 3 1 2 1 3 2 4 2 5 4 6 5 7 7 8 2 2 2 5 3 4
output:
4 5 7 8 6
result:
ok 5 number(s): "4 5 7 8 6"
Test #2:
score: -100
Runtime Error
input:
1000 500 1 500 291 2 406 9 207 13 71 15 351 17 442 18 496 19 104 20 208 23 448 34 80 42 187 44 352 45 290 46 116 47 318 50 226 52 129 55 83 59 100 60 54 61 73 65 63 66 454 67 43 71 26 74 68 26 320 75 388 76 425 79 170 81 350 83 48 85 153 86 221 90 290 95 130 96 82 98 124 82 36 99 213 100 121 101 132...