LL G[MAXN][MAXN]; inline LL Gauss(){ LL ans = 1; for (int i = 1; i < tot; i++) { for (int j = i + 1; j < tot; j++) while (G[j][i]) { LL t = G[i][i] / G[j][i]; for (int k = i; k < tot; k++) G[i][k] = ((G[i][k] - t * G[j][k]) % MOD + MOD) % MOD; swap(G[i], G[j]); ans = -ans; } ans = ans * G[i][i] % MOD; } return (ans + MOD) % MOD; }
inlinevoidadd(int u, int v){ if (u > v) return; G[u][u]++, G[v][v]++; G[u][v]--, G[v][u]--; }
intmain(){ std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); cin >> n >> m; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) { char ch; cin >> ch; if (ch == '.') mp[i][j] = ++tot; } for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) { int u = mp[i][j], v; if (!u) continue; if (v = mp[i - 1][j]) add(u, v); if (v = mp[i + 1][j]) add(u, v); if (v = mp[i][j - 1]) add(u, v); if (v = mp[i][j + 1]) add(u, v); } cout << Gauss() << endl; return0; }
inline LL qpow(LL a, LL b){ LL res = 1; while (b) { if (b & 1) res = res * a % MOD; a = a * a % MOD; b >>= 1; } return res; }
LL K[110][110], K2[32][110][110]; LL gauss(int n){ //求矩阵K的n-1阶顺序主子式 LL res = 1; for (int i = 1; i <= n - 1; i++) { //枚举主对角线上第i个元素 for (int j = i + 1; j <= n - 1; j++) { //枚举剩下的行 while (K[j][i]) { //辗转相除 int t = K[i][i] / K[j][i]; for (int k = i; k <= n - 1; k++) //转为倒三角 K[i][k] = (K[i][k] - t * K[j][k] + MOD) % MOD; swap(K[i], K[j]); //交换i、j两行 res = -res; //取负 } } res = (res * K[i][i]) % MOD; } return (res + MOD) % MOD; }
LL gauss2(int n, int bit){ //求矩阵K的n-1阶顺序主子式 LL res = 1; for (int i = 1; i <= n - 1; i++) { //枚举主对角线上第i个元素 for (int j = i + 1; j <= n - 1; j++) { //枚举剩下的行 while (K2[bit][j][i]) { //辗转相除 int t = K2[bit][i][i] / K2[bit][j][i]; for (int k = i; k <= n - 1; k++) //转为倒三角 K2[bit][i][k] = (K2[bit][i][k] - t * K2[bit][j][k] + MOD) % MOD; swap(K2[bit][i],K2[bit][j]); //交换i、j两行 res = -res; //取负 } } res = (res * K2[bit][i][i]) % MOD; } return (res + MOD) % MOD; }
intmain(){ std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); cin >> t; while (t--) { memset(K, 0, sizeof(K)); memset(K2, 0, sizeof(K2)); cin >> n >> m; LL ans = 0; for (int i = 1, u, v, w; i <= m; i++) { cin >> u >> v >> w; for (int j = 0; j < 31; j++) { int tmp = (w & (1 << j)); if (tmp) { K2[j][u][u]++, K2[j][v][v]++; K2[j][u][v]--, K2[j][v][u]--; } } K[u][u]++, K[v][v]++; K[u][v]--, K[v][u]--; } LL fenMu = gauss(n); for (int i = 0; i < 31; i++) { ans = (ans + ((gauss2(n, i) << i) % MOD)) % MOD; } cout << ans * qpow(fenMu, MOD - 2) % MOD << "\n"; } return0; }
constexprint MAXN = 105; constexprint MOD = 31011;
int n, m, ans = 1, fa[MAXN], vis[MAXN], belong[MAXN]; vector<pair<int, pair<int, int>>> vec, eTree;
inlineintfind(int x){ return fa[x] == x ? x : fa[x] = find(fa[x]); }
inlinevoidUnion(int a, int b){ int r1 = find(a), r2 = find(b); if (r1 != r2) fa[r1] = r2; }
inlinevoidkruskal(int cnt = 0){ for (int i = 1; i <= n; i++) fa[i] = i; sort(vec.begin(), vec.end()); for (auto& e : vec) { int w = e.first, u = e.second.first, v = e.second.second; if (find(u) != find(v)) { cnt++; Union(u, v); eTree.push_back(make_pair(w, make_pair(u, v))); } if (cnt == n - 1) break; } }
int G[MAXN][MAXN]; inline LL Gauss(int n){ LL ans = 1; for (int i = 1; i < n; i++) { for (int j = i + 1; j < n; j++) while (G[j][i]) { LL t = G[i][i] / G[j][i]; for (int k = i; k < n; k++) G[i][k] = ((G[i][k] - t * G[j][k]) % MOD + MOD) % MOD; swap(G[i], G[j]); ans = -ans; } ans = ans * G[i][i] % MOD; } return (ans + MOD) % MOD; }
inlinevoidadd(int u, int v){ G[u][u]++, G[v][v]++, G[u][v]--, G[v][u]--; }
inlineintcalc(int res = 1){ for (int i = 0; i < eTree.size(); i++) { if (i && eTree[i - 1].first == eTree[i].first) continue; int cnt = 0; memset(G, 0, sizeof(G)), memset(vis, 0, sizeof(vis)); for (int j = 1; j <= n; j++) fa[j] = j; for (auto& e : eTree) { //生成树上权值不为eTree[i]的边,求出联通块 int w = e.first, u = e.second.first, v = e.second.second; if (w == eTree[i].first) continue; Union(u, v); } for (int j = 1; j <= n; j++) {//处理连通块数目 方便后续生成树Gauss计数 if (!vis[find(j)]) vis[find(j)] = ++cnt; belong[j] = vis[find(j)]; } for (auto& e : vec) { //所有边,将连通块相连 int w = e.first, u = e.second.first, v = e.second.second; if (w != eTree[i].first) continue; add(belong[u], belong[v]); //加边 } res = res * Gauss(cnt) % MOD; } return res; }
intmain(){ std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); cin >> n >> m; for (int i = 1, u, v, w; i <= m; i++) { cin >> u >> v >> w; vec.push_back(make_pair(w, make_pair(u, v))); } kruskal(); cout << calc() << endl; return0; }
int G[MAXN][MAXN]; inlineintGauss(int n, int res = 1){ for (int i = 2; i <= n; i++) { for (int j = i + 1; j <= n; j++) { while (G[j][i]) { int t = G[i][i] / G[j][i]; for (int k = i; k <= n; k++) G[i][k] = ((G[i][k] - t * G[j][k]) % MOD + MOD) % MOD; swap(G[i], G[j]); res = -res; } } res = res * G[i][i] % MOD; } return (res + MOD) % MOD; } /*从 u 到 v 的有向边*/ inlinevoidadd(int u, int v){ G[u][v]--, G[u][u]++; }
signedmain(){ std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); cin >> n >> m; while (m--) cin >> u >> v, add(u, v); cout << Gauss(n) << endl; return0; }