// DSU vector<int> dsuRoot(n); vector<vector<int>> dsuElem(n); for (int i = 0; i < n; i++) { dsuRoot[i] = i; dsuElem[i].push_back(i); } auto uno = [&](int u, int v) { u = dsuRoot[u]; v = dsuRoot[v]; // 并查集找根 if (u == v) { continue; // 如果已经在同一个集合里,就不需要合并 } if (dsuElem[u].size() < dsuElem[v].size()) { swap(u, v); // 让小集合合并到大集合里 } for (auto x : dsuElem[v]) { dsuElem[u].push_back(x); // 合并 dsuRoot[x] = u; } };
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;