vector<vector<int>> dsu(n); for (int i = 0; i < n; i++) { dsu[i].push_back(i); } auto uno = [&](int x, int y) { if (x = dsu[x][0], y = dsu[y][0]; x == y) { return; // 如果已经在同一个集合里,就不需要合并 } if (dsu[x].size() < dsu[y].size()) { swap(x, y); // 让小集合合并到大集合里 } for (auto z : dsu[y]) { // 不能写成 for (int i = 0; i < dsu[y].size(); i++) dsu[x].push_back(z); // 合并 dsu[z] = { x }; } };
int N, n; cin >> N >> n; vector<int> color(N); for (int i = 0; i < N; i++) { cin >> color[i]; color[i]--; } vector<vector<int>> E(n); int m; cin >> m; constint B = ceil(sqrt(2 * m)); while (m--) { int u, v; cin >> u >> v; u--; v--; E[u].push_back(v); if (u != v) { // 注意自环 E[v].push_back(u); } } vector<vector<int>> G(n); for (int u = 0; u < n; u++) { for (auto v : E[u]) { if (E[v].size() > B) { G[u].push_back(v); // 所有点连大点 } } } vector<Z> val(n), lazy(n), dp(N); for (int x = 0; x < N; x++) { int u = color[x]; if (x == 0) { dp[x] = 1; } elseif (E[u].size() > B) { // 大点直接用 lazyTag dp[x] = lazy[u]; } elsefor (auto v : E[u]) { // 小点暴力更新 dp[x] += val[v]; } val[u] += dp[x]; for (auto v : G[u]) { // 把信息送给大点 lazy[v] += dp[x]; } } cout << dp.back() << endl;
intmain(){ #define ls (p<<1) #define rs (p<<1|1) #define mid ((L+R)>>1)
int n, m; cin >> n >> m;
vector<vector<pair<int, int>>> E(n << 2); while (m--) { int u, v, l, r; cin >> u >> v >> l >> r; u--, v--; l--; if (u > v) swap(u, v); auto add = [&](thisauto&& add, int p, int L, int R) -> void { if (l <= L && R <= r) { E[p].push_back({ u, v }); } elseif (l < R && L < r) { add(ls, L, mid), add(rs, mid, R); } }; add(1, 0, n); }
DSU dsu(n); auto solve = [&](thisauto&& solve, int p, int L, int R) -> void { int h = dsu.now(); for (auto [u, v] : E[p]) { dsu.uno(u, v); } if (R - L == 1) { dsu.lazy[dsu.find(0)] += L + 1; } else { solve(ls, L, mid), solve(rs, mid, R); } return dsu.undo(h); }; solve(1, 0, n);
ll res = 0; for (int i = 0; i < n; i++) { res ^= dsu.lazy[i]; } cout << res << endl;