QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#877787 | #8616. Fast Tree Queries | hos_lyric | TL | 2595ms | 18904kb | C++14 | 7.5kb | 2025-02-01 08:35:25 | 2025-02-01 08:35:25 |
Judging History
answer
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#pragma GCC target("avx2")
using namespace std;
using Int = long long;
template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
#define COLOR(s) ("\x1b[" s "m")
struct Hld {
int n, rt;
// needs to be tree
// vertex lists
// modified in build(rt) (parent removed, heavy child first)
vector<vector<int>> graph;
vector<int> sz, par, dep;
int zeit;
vector<int> dis, fin, sid;
// head vertex (minimum depth) in heavy path
vector<int> head;
Hld() : n(0), rt(-1), zeit(0) {}
explicit Hld(int n_) : n(n_), rt(-1), graph(n), zeit(0) {}
void ae(int u, int v) {
assert(0 <= u); assert(u < n);
assert(0 <= v); assert(v < n);
graph[u].push_back(v);
graph[v].push_back(u);
}
void dfsSz(int u) {
sz[u] = 1;
for (const int v : graph[u]) {
auto it = std::find(graph[v].begin(), graph[v].end(), u);
if (it != graph[v].end()) graph[v].erase(it);
par[v] = u;
dep[v] = dep[u] + 1;
dfsSz(v);
sz[u] += sz[v];
}
}
void dfsHld(int u) {
dis[u] = zeit++;
const int deg = graph[u].size();
if (deg > 0) {
int vm = graph[u][0];
int jm = 0;
for (int j = 1; j < deg; ++j) {
const int v = graph[u][j];
if (sz[vm] < sz[v]) {
vm = v;
jm = j;
}
}
swap(graph[u][0], graph[u][jm]);
head[vm] = head[u];
dfsHld(vm);
for (int j = 1; j < deg; ++j) {
const int v = graph[u][j];
head[v] = v;
dfsHld(v);
}
}
fin[u] = zeit;
}
void build(int rt_) {
assert(0 <= rt_); assert(rt_ < n);
rt = rt_;
sz.assign(n, 0);
par.assign(n, -1);
dep.assign(n, -1);
dep[rt] = 0;
dfsSz(rt);
zeit = 0;
dis.assign(n, -1);
fin.assign(n, -1);
head.assign(n, -1);
head[rt] = rt;
dfsHld(rt);
assert(zeit == n);
sid.assign(n, -1);
for (int u = 0; u < n; ++u) sid[dis[u]] = u;
}
friend ostream &operator<<(ostream &os, const Hld &hld) {
const int maxDep = *max_element(hld.dep.begin(), hld.dep.end());
vector<string> ss(2 * maxDep + 1);
int pos = 0, maxPos = 0;
for (int j = 0; j < hld.n; ++j) {
const int u = hld.sid[j];
const int d = hld.dep[u];
if (hld.head[u] == u) {
if (j != 0) {
pos = maxPos + 1;
ss[2 * d - 1].resize(pos, '-');
ss[2 * d - 1] += '+';
}
} else {
ss[2 * d - 1].resize(pos, ' ');
ss[2 * d - 1] += '|';
}
ss[2 * d].resize(pos, ' ');
ss[2 * d] += std::to_string(u);
if (maxPos < static_cast<int>(ss[2 * d].size())) {
maxPos = ss[2 * d].size();
}
}
for (int d = 0; d <= 2 * maxDep; ++d) os << ss[d] << '\n';
return os;
}
bool contains(int u, int v) const {
return (dis[u] <= dis[v] && dis[v] < fin[u]);
}
int lca(int u, int v) const {
assert(0 <= u); assert(u < n);
assert(0 <= v); assert(v < n);
for (; head[u] != head[v]; ) (dis[u] > dis[v]) ? (u = par[head[u]]) : (v = par[head[v]]);
return (dis[u] > dis[v]) ? v : u;
}
int jumpUp(int u, int d) const {
assert(0 <= u); assert(u < n);
assert(d >= 0);
if (dep[u] < d) return -1;
const int tar = dep[u] - d;
for (u = head[u]; ; u = head[par[u]]) {
if (dep[u] <= tar) return sid[dis[u] + (tar - dep[u])];
}
}
int jump(int u, int v, int d) const {
assert(0 <= u); assert(u < n);
assert(0 <= v); assert(v < n);
assert(d >= 0);
const int l = lca(u, v);
const int du = dep[u] - dep[l], dv = dep[v] - dep[l];
if (d <= du) {
return jumpUp(u, d);
} else if (d <= du + dv) {
return jumpUp(v, du + dv - d);
} else {
return -1;
}
}
// [u, v) or [u, v]
template <class F> void doPathUp(int u, int v, bool inclusive, F f) const {
assert(contains(v, u));
for (; head[u] != head[v]; u = par[head[u]]) f(dis[head[u]], dis[u] + 1);
if (inclusive) {
f(dis[v], dis[u] + 1);
} else {
if (v != u) f(dis[v] + 1, dis[u] + 1);
}
}
// not path order, include lca(u, v) or not
template <class F> void doPath(int u, int v, bool inclusive, F f) const {
const int l = lca(u, v);
doPathUp(u, l, false, f);
doPathUp(v, l, inclusive, f);
}
// (vs, ps): compressed tree
// vs: DFS order (sorted by dis)
// vs[ps[x]]: the parent of vs[x]
// ids[vs[x]] = x, not set for non-tree vertex
vector<int> ids;
pair<vector<int>, vector<int>> compress(vector<int> us) {
// O(n) first time
ids.resize(n, -1);
std::sort(us.begin(), us.end(), [&](int u, int v) -> bool {
return (dis[u] < dis[v]);
});
us.erase(std::unique(us.begin(), us.end()), us.end());
int usLen = us.size();
assert(usLen >= 1);
for (int x = 1; x < usLen; ++x) us.push_back(lca(us[x - 1], us[x]));
std::sort(us.begin(), us.end(), [&](int u, int v) -> bool {
return (dis[u] < dis[v]);
});
us.erase(std::unique(us.begin(), us.end()), us.end());
usLen = us.size();
for (int x = 0; x < usLen; ++x) ids[us[x]] = x;
vector<int> ps(usLen, -1);
for (int x = 1; x < usLen; ++x) ps[x] = ids[lca(us[x - 1], us[x])];
return make_pair(us, ps);
}
};
////////////////////////////////////////////////////////////////////////////////
int N, Q;
vector<int> A, B;
int main() {
for (; ~scanf("%d%d", &N, &Q); ) {
A.resize(N - 1);
B.resize(N - 1);
for (int i = 0; i < N - 1; ++i) {
scanf("%d%d", &A[i], &B[i]);
--A[i];
--B[i];
}
Hld hld(N);
for (int i = 0; i < N - 1; ++i) {
hld.ae(A[i], B[i]);
}
hld.build(0);
vector<int> fs(N);
for (int j = 0; j < N; ++j) fs[j] = hld.sid[j] + 1;
for (; Q--; ) {
char O;
int U, V;
scanf(" %c%d%d", &O, &U, &V);
--U;
--V;
if (O == '+') {
int X;
scanf("%d", &X);
hld.doPath(U, V, true, [&](int l, int r) -> void {
for (int j = l; j < r; ++j) fs[j] += X;
});
} else if (O == '?') {
int ans = 0;
hld.doPath(U, V, true, [&](int l, int r) -> void {
for (int j = l; j < r; ++j) ans ^= fs[j];
});
printf("%d\n", ans);
} else {
assert(false);
}
}
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 3968kb
input:
5 6 1 2 1 3 3 4 3 5 ? 2 5 + 1 4 1 ? 2 5 + 4 5 2 ? 4 5 ? 1 1
output:
5 1 6 2
result:
ok 4 number(s): "5 1 6 2"
Test #2:
score: 0
Accepted
time: 0ms
memory: 3840kb
input:
100 100 6 74 6 93 7 46 7 78 10 77 11 9 11 19 11 37 11 51 11 65 12 57 13 15 13 81 13 100 14 2 14 31 16 11 16 24 16 43 16 82 18 4 18 8 21 56 24 29 24 96 26 22 27 32 28 59 29 6 29 94 32 33 35 54 35 80 35 88 37 66 37 71 37 84 38 17 39 64 39 92 40 49 43 7 43 13 43 44 43 79 44 35 44 60 44 63 44 73 46 75 4...
output:
106 66 23766 20394 16388 3365 12076 7844 43127 56700 59 34700 24083 1164 24068 18776 3375 17495 21576 63126 11157 108177 63127 99162 105173 10715 110921 18320 19725 30958 120179 81226 107525 15669 21804 31071 63099 8313 191380 232240 84531 89146 173181 5447 160027 228651 98075 32595 109808 221822 11...
result:
ok 51 numbers
Test #3:
score: 0
Accepted
time: 5ms
memory: 4636kb
input:
10000 10000 1 8776 3 1597 3 8333 4 675 4 6993 4 7587 5 3379 5 6733 7 2440 7 6480 7 9506 10 4545 10 6664 12 1476 12 5343 14 1340 14 4167 14 5990 14 9910 15 5118 15 9423 16 8106 17 3856 20 5201 23 1138 24 3431 24 5578 25 251 26 3219 26 4156 26 6668 27 3795 28 6282 28 8196 34 9595 35 3919 36 5893 37 58...
output:
9911 12310 4793 31764 2730 42301 62944 16978 8306 25311 3011 1327 48224 8407 15662 38117 42837 59074 40600 39018 126441 21755 24519 51286 121187 4335 8349 10553 60726 86675 10797 3883 90069 95477 129342 37777 42339 124045 94323 16858 217612 79454 258856 118337 257945 196316 170121 216631 168616 1663...
result:
ok 5012 numbers
Test #4:
score: 0
Accepted
time: 33ms
memory: 8192kb
input:
50000 50000 1 1362 3 3371 3 13803 3 41794 3 47253 5 6227 5 42748 5 47841 6 28509 6 47395 7 8651 8 35909 10 24241 10 31205 10 33574 10 44109 10 48982 12 31361 12 44645 13 42041 15 20480 16 9467 16 11685 16 16024 16 28894 16 30759 19 3485 19 23470 19 24714 22 14239 25 44841 31 20447 35 5378 35 45983 3...
output:
5042 36803 61033 62216 64370 9744 33748 43519 25564 87892 120265 52351 36778 1507 81138 124599 19620 169852 82219 106112 38410 47506 214605 229380 175036 184353 71808 135637 195043 213707 60790 86453 31176 26740 107180 117349 64903 55397 245841 33362 73881 227391 227333 52027 217335 146795 51029 100...
result:
ok 24888 numbers
Test #5:
score: 0
Accepted
time: 68ms
memory: 13020kb
input:
100000 100000 4 6907 4 36895 4 37669 4 43936 4 99352 5 70501 10 29516 11 2844 11 77315 13 67782 13 72511 14 17273 14 52833 16 97869 19 29567 20 150 20 22843 20 40110 20 55549 20 70574 22 19544 25 43083 26 6781 28 16286 31 54186 33 6987 33 30861 33 98931 35 1140 35 21137 35 26681 35 59133 35 68440 35...
output:
81605 93578 30029 52473 57143 63629 77074 53264 71956 49059 16958 120352 93046 80080 67928 99557 182425 198595 36952 180370 156161 98094 56273 28969 34287 146511 31057 171228 128057 13930 81021 69266 100431 118091 249004 63451 147951 223183 255240 173677 30490 137681 135801 8441 205904 32855 66449 2...
result:
ok 50026 numbers
Test #6:
score: 0
Accepted
time: 147ms
memory: 12976kb
input:
100000 100000 1 484 1 23605 4 29115 5 78235 6 41049 7 17427 7 59118 7 73639 8 11499 8 21824 11 1488 11 34365 11 46659 15 1670 15 18862 16 88552 17 6551 17 18453 17 22090 18 90500 19 7369 19 40175 19 88031 19 89418 20 82312 22 36035 22 37511 22 90587 24 26545 25 99359 26 9713 26 19360 26 23939 27 145...
output:
118339 49557 8069 129295 8844 117076 73582 44568 123694 84080 220459 65210 20353 78112 178132 238977 76360 242837 177610 55964 146913 258846 46783 101598 210987 130886 215693 137264 91070 47636 222290 212175 70753 64509 143987 258750 63355 124572 249779 144712 237288 64472 32941 26055 220986 221734 ...
result:
ok 50004 numbers
Test #7:
score: 0
Accepted
time: 1327ms
memory: 15708kb
input:
100000 100000 2 96325 3 2625 3 19305 3 23547 3 33880 4 34351 4 80895 6 81122 7 8449 8 33132 9 6805 10 66297 12 40279 15 97995 17 28489 17 58943 17 63155 18 16755 19 36111 19 48497 20 73429 21 58028 22 23782 23 23210 25 43059 25 98782 28 96774 29 13371 30 18348 30 33119 31 91098 32 20761 34 19579 34 ...
output:
127926 27191 52198 17494 136 89133 88302 171 53017 111240 104493 80525 30736 39514 30186 242564 127960 116595 77217 181066 78202 117647 65124 5801 23054 231346 224212 101596 208931 56567 153986 225153 98732 39206 196696 201593 49107 59019 227567 23907 240224 47177 110143 93337 12687 16281 91369 7419...
result:
ok 49756 numbers
Test #8:
score: 0
Accepted
time: 1960ms
memory: 17280kb
input:
100000 100000 1 18235 1 18934 2 89403 2 90291 3 31647 3 35123 4 14885 5 62625 6 75214 6 78206 6 86462 8 68147 10 73927 12 70742 13 18440 13 52686 14 486 15 38714 17 22417 19 10945 20 65914 22 168 24 72860 24 77513 25 43311 28 65572 31 24246 31 59430 32 26581 33 50532 35 41198 35 50438 38 10180 39 26...
output:
22351 118753 109047 88534 43548 60668 10313 43770 93628 94411 177029 257319 102775 45279 115695 72012 192085 82192 95036 247561 261897 165855 165273 226260 148341 25180 217815 163115 16411 218342 48666 2097 28168 215064 103606 87112 56628 51686 160381 172733 114741 224702 118590 202031 122700 81734 ...
result:
ok 50083 numbers
Test #9:
score: 0
Accepted
time: 2595ms
memory: 18904kb
input:
100000 100000 1 11525 1 89745 2 67284 3 9976 4 50748 5 77041 6 78293 7 56148 8 96259 9 89843 10 27797 11 16227 12 42015 13 68712 14 79151 15 28737 16 12689 16 46963 17 28758 17 97100 18 9035 18 45786 19 90894 20 6079 21 74811 22 59751 24 46439 25 61997 26 49256 27 47844 27 94562 28 36184 28 66803 29...
output:
27686 112778 112901 88910 1259 100292 96264 120935 67017 16105 254118 72138 79696 90798 240510 79481 58592 122335 35752 50037 4041 228323 26517 261989 101035 109710 124017 214226 78961 147898 227267 88759 232759 3546 176037 13839 58194 199727 72664 208807 235932 95313 72316 175531 185967 46635 25389...
result:
ok 50026 numbers
Test #10:
score: -100
Time Limit Exceeded
input:
100000 100000 1 8418 2 20507 3 79696 4 480 5 96826 6 39218 7 33218 8 91962 9 61011 10 76027 11 51859 12 47310 13 9311 14 62652 15 54337 16 37358 17 8695 18 30671 19 48794 20 60657 21 52785 22 67049 23 53237 24 89488 25 75316 26 59632 27 67663 28 64116 29 55756 30 9293 31 94163 32 68737 33 19549 34 2...
output:
59881 78759 127664 105428 29216 107850 23544 72603 31268 104150 10678 99895 191639 208183 143507 28071 112078 206140 244014 94502 180431 86547 228779 253881 114121 78644 211819 183217 3147 260855 252995 92807 134492 222747 179363 178012 163544 6300 56553 216082 135851 241124 54901 160545 83866 34670...