G - Xor-matic Number of the Graph
上一道题的加强版本,对于每个联通块需要按位算贡献。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PII pair<int, int> #define PLI pair<LL, int> #define ull unsigned long long using namespace std; const int N = 1e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; int n, m; LL d[N], bin[N], num[2]; bool vis[N]; vector<PLI> edge[N]; vector<int> id; struct Base { LL a[63]; int cnt; void init() { memset(a, 0, sizeof(a)); cnt = 0; } void add(LL x) { for(int j = 62; ~j; j--) { if((x >> j) & 1) { if(!a[j]) {a[j]=x; cnt++; break;} else x ^= a[j]; } } } } base; void dfs(int u, int fa) { vis[u] = true; id.push_back(u); for(int i = 0; i < edge[u].size(); i++) { int v = edge[u][i].se; LL w = edge[u][i].fi; if(v == fa) continue; if(vis[v]) { base.add(d[u]^d[v]^w); } else { d[v] = d[u] ^ w; dfs(v, u); } } } int main() { base.pirnt(); scanf("%d%d", &n, &m); for(int i=bin[0]=1; i <= n; i++) bin[i] = bin[i-1] * 2 % mod; for(int i = 1; i <= m; i++) { int u, v; LL w; scanf("%d%d%lld", &u, &v, &w); edge[u].push_back(mk(w, v)); edge[v].push_back(mk(w, u)); } LL ans = 0; for(int i = 1; i <= n; i++) { if(!vis[i]) { base.init(); id.clear(); dfs(i, 0); for(int j = 0; j <= 62; j++) { num[0] = 0, num[1] = 0; for(auto &x : id) { num[(d[x]>>j)&1]++; } bool flag = false; for(int k = 0; k < 63; k++) { if((base.a[k]>>j)&1) { flag = true; break; } } LL tmp = num[0]*(num[0]-1)/2 + num[1]*(num[1]-1)/2; tmp %= mod; if(flag) ans = (ans + bin[j]*bin[base.cnt-1]%mod*tmp%mod) % mod; tmp = num[0] * num[1] % mod; if(flag) ans = (ans + bin[j]*bin[base.cnt-1]%mod*tmp%mod) % mod; else ans = (ans + bin[j]*bin[base.cnt]%mod*tmp%mod) % mod; } } } printf("%lld ", ans); return 0; } /* */