QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#877787#8616. Fast Tree Querieshos_lyricTL 2595ms18904kbC++147.5kb2025-02-01 08:35:252025-02-01 08:35:25

Judging History

This is the latest submission verdict.

  • [2025-02-01 08:35:25]
  • Judged
  • Verdict: TL
  • Time: 2595ms
  • Memory: 18904kb
  • [2025-02-01 08:35:25]
  • Submitted

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...

result: