QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#180672#4891. 树上的孤独hos_lyric#10 14ms4104kbC++148.1kb2023-09-16 07:18:522024-07-04 02:00:52

Judging History

你现在查看的是最新测评结果

  • [2024-07-04 02:00:52]
  • 评测
  • 测评结果:10
  • 用时:14ms
  • 内存:4104kb
  • [2023-09-16 07:18:52]
  • 提交

answer

#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 <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

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")


int N[2], Q;
vector<int> A[2], B[2];
vector<int> C[2];
vector<int> O, X[4];
int K;

vector<vector<int>> graph[2];
int zeit[2];
vector<int> dep[2], dis[2], fin[2];
void dfs(int h, int u, int p) {
  dep[h][u] = (~p) ? (dep[h][p] + 1) : 0;
  dis[h][u] = zeit[h]++;
  for (const int v : graph[h][u]) if (p != v) {
    dfs(h, v, u);
  }
  fin[h][u] = zeit[h];
}


namespace brute {
vector<int> run() {
  vector<int> css[2] = {C[0], C[1]};
  vector<int> ans(Q, 0);
  vector<int> on(K, -1);
  int lt = 0;
  for (int q = 0; q < Q; ++q) {
    if (O[q] == 1) {
      const int R[2] = {X[0][q], X[1][q]};
      const int D[2] = {X[2][q] ^ lt, X[3][q] ^ lt};
// cerr<<COLOR("33")<<"calc "<<R[0]<<","<<D[0]<<" "<<R[1]<<","<<D[1]<<COLOR()<<endl;
      for (int h = 0; h < 2; ++h) for (int u = 0; u < N[h]; ++u) {
        if (dis[h][R[h]] <= dis[h][u] && dis[h][u] < fin[h][R[h]] && dep[h][u] <= dep[h][R[h]] + D[h]) {
// cerr<<"  "<<h<<" "<<u<<endl;
          on[css[h][u]] = q;
        }
      }
      for (int k = 0; k < K; ++k) if (on[k] == q) {
        ++ans[q];
      }
      lt = ans[q];
    } else if (O[q] == 2) {
// cerr<<COLOR("33")<<"change "<<X[0][q]<<" "<<X[1][q]<<endl;
      css[0][X[0][q]] = X[1][q];
    } else {
      assert(false);
    }
  }
  return ans;
}
}  // brute


namespace fast {
constexpr int INF = 1001001001;

vector<vector<int>> c0ss;
vector<vector<int>> qss;
vector<vector<int>> dss;

struct Node {
  int l, r;
  int sum;
};
int segN;
int V;
Node nodes[150'000'010];
void init() {
  V = 1;
  const int maxDep1 = *max_element(dep[1].begin(), dep[1].end());
  for (segN = 1; segN < maxDep1 + 1; segN <<= 1) {}
}
void pull(int u) {
  nodes[u].sum = nodes[nodes[u].l].sum + nodes[nodes[u].r].sum;
}
int pointAdd(int u, int L, int R, int a, int val) {
  if (!(L <= a && a < R)) return u;
  if (L + 1 == R) {
    const int v = V++;
    nodes[v].sum = nodes[u].sum + val;
    return v;
  }
  const int Mid = (L + R) >> 1;
  const int l = pointAdd(nodes[u].l, L, Mid, a, val);
  const int r = pointAdd(nodes[u].r, Mid, R, a, val);
  const int v = V++;
  nodes[v].l = l;
  nodes[v].r = r;
  pull(v);
  return v;
}
int rangeSum(int u, int L, int R, int a, int b) {
  if (!u) return 0;
  if (b <= L || R <= a) return 0;
  if (a <= L && R <= b) return nodes[u].sum;
  const int Mid = (L + R) >> 1;
  const int resL = rangeSum(nodes[u].l, L, Mid, a, b);
  const int resR = rangeSum(nodes[u].r, Mid, R, a, b);
  return resL + resR;
}

// node id
vector<int> dp;
// (color -> min dep)
map<int, int> solve(int u, int p) {
  map<int, int> ret;
  ret[C[1][u]] = dep[1][u];
  dp[u] = pointAdd(dp[u], 0, segN, dep[1][u], +1);
  for (const int v : graph[1][u]) if (p != v) {
    auto res = solve(v, u);
    if (ret.size() < res.size()) {
      ret.swap(res);
      dp[u] = dp[v];
    }
    for (const auto &kv : res) {
      auto it = ret.find(kv.first);
      if (it != ret.end()) {
        if (it->second > kv.second) {
          dp[u] = pointAdd(dp[u], 0, segN, it->second, -1);
          dp[u] = pointAdd(dp[u], 0, segN, kv.second, +1);
          it->second = kv.second;
        }
      } else {
        ret.insert(kv);
        dp[u] = pointAdd(dp[u], 0, segN, kv.second, +1);
      }
    }
  }
  for (const int q : qss[u]) {
    dss[q].assign(N[0], INF);
    for (int u0 = 0; u0 < N[0]; ++u0) {
      auto it = ret.find(c0ss[q][u0]);
      if (it != ret.end()) {
        dss[q][u0] = it->second;
      }
    }
  }
  return ret;
}

vector<int> run() {
  auto c0s = C[0];
  c0ss.assign(Q, {});
  qss.assign(N[1], {});
  for (int q = 0; q < Q; ++q) {
    if (O[q] == 1) {
      c0ss[q] = c0s;
      qss[X[1][q]].push_back(q);
    } else if (O[q] == 2) {
      c0s[X[0][q]] = X[1][q];
    } else {
      assert(false);
    }
  }
  
  dss.assign(Q, {});
  dp.assign(N[1], 0);
  solve(0, -1);
  
  vector<int> ans(Q, 0);
  int lt = 0;
  for (int q = 0; q < Q; ++q) if (O[q] == 1) {
    const int R[2] = {X[0][q], X[1][q]};
    const int D[2] = {X[2][q] ^ lt, X[3][q] ^ lt};
    
    // TODO
    /*
    set<int> ss;
    for (int u = 0; u < N[1]; ++u) {
      if (dis[1][R[1]] <= dis[1][u] && dis[1][u] < fin[1][R[1]] && dep[1][u] <= dep[1][R[1]] + D[1]) {
        ss.insert(C[1][u]);
      }
    }
    ans[q] = ss.size();
    */
    ans[q] = rangeSum(dp[R[1]], 0, segN, dep[1][R[1]], dep[1][R[1]] + D[1] + 1);
    
    for (int u = 0; u < N[0]; ++u) {
      if (dis[0][R[0]] <= dis[0][u] && dis[0][u] < fin[0][R[0]] && dep[0][u] <= dep[0][R[0]] + D[0]) {
        if (dss[q][u] > dep[1][R[1]] + D[1]) {
          ++ans[q];
        }
      }
    }
    lt = ans[q];
  }
  return ans;
}
}  // fast


int main() {
  for (; ~scanf("%d%d%d", &N[0], &N[1], &Q); ) {
    for (int h = 0; h < 2; ++h) {
      A[h].resize(N[h] - 1);
      B[h].resize(N[h] - 1);
      for (int i = 0; i < N[h] - 1; ++i) {
        scanf("%d%d", &A[h][i], &B[h][i]);
        --A[h][i];
        --B[h][i];
      }
    }
    for (int h = 0; h < 2; ++h) {
      C[h].resize(N[h]);
      for (int u = 0; u < N[h]; ++u) {
        scanf("%d", &C[h][u]);
      }
    }
    O.resize(Q);
    X[0].assign(Q, -1);
    X[1].assign(Q, -1);
    X[2].assign(Q, -1);
    X[3].assign(Q, -1);
    for (int q = 0; q < Q; ++q) {
      scanf("%d%d%d", &O[q], &X[0][q], &X[1][q]);
      if (O[q] == 1) {
        scanf("%d%d", &X[2][q], &X[3][q]);
        --X[0][q];
        --X[1][q];
      } else if (O[q] == 2) {
        --X[0][q];
      } else {
        assert(false);
      }
    }
    
    {
      vector<int> cs;
      for (int h = 0; h < 2; ++h) for (int u = 0; u < N[h]; ++u) {
        cs.push_back(C[h][u]);
      }
      for (int q = 0; q < Q; ++q) if (O[q] == 2) {
        cs.push_back(X[1][q]);
      }
      sort(cs.begin(), cs.end());
      cs.erase(unique(cs.begin(), cs.end()), cs.end());
      K = cs.size();
      auto indexOf = [&](int c) -> int {
        return lower_bound(cs.begin(), cs.end(), c) - cs.begin();
      };
      for (int h = 0; h < 2; ++h) for (int u = 0; u < N[h]; ++u) {
        C[h][u] = indexOf(C[h][u]);
      }
      for (int q = 0; q < Q; ++q) if (O[q] == 2) {
        X[1][q] = indexOf(X[1][q]);
      }
    }
// cerr<<"K = "<<K<<", C[0] = "<<C[0]<<", C[1] = "<<C[1]<<endl;
    
    for (int h = 0; h < 2; ++h) {
      graph[h].assign(N[h], {});
      for (int i = 0; i < N[h] - 1; ++i) {
        graph[h][A[h][i]].push_back(B[h][i]);
        graph[h][B[h][i]].push_back(A[h][i]);
      }
      zeit[h] = 0;
      dep[h].assign(N[h], -1);
      dis[h].assign(N[h], -1);
      fin[h].assign(N[h], -1);
      dfs(h, 0, -1);
    }
    
    const auto ans = brute::run();
    for (int q = 0; q < Q; ++q) if (O[q] == 1) {
      printf("%d\n", ans[q]);
    }
#ifdef LOCAL
const auto brt=brute::run();
assert(brt==ans);
#endif
  }
  return 0;
}

详细

Subtask #1:

score: 10
Accepted

Test #1:

score: 10
Accepted
time: 14ms
memory: 4012kb

input:

20 2000 2000
8 15
8 13
14 8
14 7
12 14
12 1
9 13
9 4
5 9
5 10
2 5
2 19
6 19
6 16
11 7
11 20
18 2
18 17
3 6
1395 1783
1395 1735
1735 457
457 739
739 438
438 101
101 441
441 1879
1879 1238
1238 501
501 1732
1732 1910
1910 2000
2000 834
834 917
917 111
111 780
780 1966
1966 1604
1604 623
623 1748
1748 ...

output:

105
93
2
44
19
54
192
25
69
21
21
200
78
88
137
33
68
68
54
35
24
8
23
78
59
100
27
200
40
74
97
21
87
36
197
76
28
49
11
20
55
60
24
5
109
158
23
21
15
102
36
108
26
78
171
82
32
147
145
9
136
31
109
142
119
68
34
64
18
40
56
48
54
14
35
154
111
130
144
200
21
80
84
37
73
24
28
37
160
51
62
51
95
2...

result:

ok 1481 numbers

Test #2:

score: 10
Accepted
time: 13ms
memory: 4104kb

input:

20 2000 2000
7 9
7 4
20 4
20 15
19 7
19 3
11 9
11 8
5 19
5 1
13 19
13 10
12 5
6 3
17 8
17 14
2 3
2 18
16 5
304 1166
304 1254
1254 1939
1939 430
430 1573
1573 1917
1917 934
934 226
226 1722
1722 453
453 562
562 151
151 1985
1985 1689
1689 1492
1492 108
108 948
948 753
753 92
92 1347
1347 1940
1940 10...

output:

34
197
20
99
87
35
26
19
2
36
87
19
66
199
5
156
19
35
129
62
12
199
96
19
52
4
38
198
19
200
36
60
47
64
44
172
15
48
20
166
147
53
23
46
140
48
56
77
134
39
49
200
67
19
19
40
2
19
158
24
21
79
91
45
12
126
183
20
122
29
21
28
27
65
28
58
141
25
20
172
20
3
179
7
46
141
57
57
43
150
2
86
25
8
72
2...

result:

ok 1495 numbers

Subtask #2:

score: 0
Time Limit Exceeded

Test #3:

score: 0
Time Limit Exceeded

input:

20 200000 500000
8 18
8 4
2 4
2 14
13 4
13 16
6 4
6 3
1 4
1 17
15 6
15 19
7 17
7 11
5 14
5 10
20 7
12 15
9 8
165302 77239
165302 198189
165302 180850
165302 192738
165302 173589
165302 194087
165302 191990
165302 167370
165302 101092
165302 92553
165302 163654
165302 122381
165302 152105
165302 1919...

output:


result:


Subtask #3:

score: 0
Time Limit Exceeded

Test #7:

score: 0
Time Limit Exceeded

input:

20 100000 100000
16 12
16 20
6 12
6 18
2 16
2 8
5 20
5 13
3 6
3 11
19 11
19 17
9 12
9 15
4 15
4 7
10 5
14 15
14 1
85812 94626
85812 91172
91172 93788
93788 96567
96567 75524
75524 23275
23275 98340
98340 81608
81608 91480
91480 75108
75108 56605
56605 93317
93317 41617
41617 77160
77160 727
727 7559...

output:


result:


Subtask #4:

score: 0
Time Limit Exceeded

Test #13:

score: 0
Time Limit Exceeded

input:

1 200000 500000
189127 137023
189127 199761
199761 160701
160701 130639
130639 190908
190908 176819
176819 193363
193363 188021
188021 182446
182446 186028
186028 198828
198828 190792
190792 155378
155378 189428
189428 177276
177276 146159
146159 175923
175923 188073
188073 182206
182206 131072
1310...

output:


result:


Subtask #5:

score: 0
Time Limit Exceeded

Test #15:

score: 0
Time Limit Exceeded

input:

20 200000 1000000
13 10
13 5
19 5
19 20
15 10
15 6
12 6
12 3
8 10
8 2
1 20
1 11
14 10
14 16
18 3
18 7
4 3
9 10
9 17
194055 154514
194055 148156
148156 115271
115271 198116
198116 179433
179433 171975
171975 196600
196600 167194
167194 185078
185078 191409
191409 163496
163496 178243
178243 154093
15...

output:


result: