QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#180673 | #4891. 树上的孤独 | hos_lyric# | 0 | 25ms | 4560kb | C++14 | 8.0kb | 2023-09-16 07:20:09 | 2024-07-04 02:00:55 |
Judging History
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};
//*
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 = fast::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;
}
Details
Tip: Click on the bar to expand more detailed information
Subtask #1:
score: 0
Wrong Answer
Test #1:
score: 0
Wrong Answer
time: 25ms
memory: 4560kb
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 45 19 55 192 26 69 21 22 200 79 89 137 33 68 69 55 37 24 8 24 79 59 100 27 200 40 74 97 21 87 37 197 76 28 49 11 20 55 62 24 5 109 158 25 23 15 102 38 109 28 76 172 83 31 147 145 9 136 33 109 142 120 69 35 67 20 47 59 51 56 14 35 154 111 130 144 200 21 81 83 40 73 25 30 39 163 53 62 51 97 2...
result:
wrong answer 4th numbers differ - expected: '44', found: '45'
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...