QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#751732 | #8547. Whose Land? | 000226 | WA | 555ms | 16544kb | C++17 | 5.3kb | 2024-11-15 20:21:06 | 2024-11-15 20:21:07 |
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;
if (dep[x] + k > n) 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: 16544kb
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
Wrong Answer
time: 555ms
memory: 15992kb
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...
output:
184 440 385 219 367 403 456 5 326 452 411 396 181 320 431 480 266 143 393 404 158 382 72 382 186 58 237 471 116 9 269 462 422 317 331 390 472 462 83 410 24 408 410 329 447 357 315 288 177 143 319 449 458 376 424 464 318 267 423 440 321 472 129 239 473 134 471 260 369 337 340 435 84 454 476 333 115 2...
result:
wrong answer 1st numbers differ - expected: '255', found: '184'