[BZOJ 4671]异或图
Description
给定 $s$ 个结点数相同且为 $n$ 的图 $G_1\sim G_s$ ,设 $S = {G_1, G_2,\cdots , G_s}$ ,问 $S$ 有多少个子集的异或为一个连通图。
$1\leq n\leq 10,1\leq s\leq 60$
Solution
不妨记 $f_x$ 为连通块个数至少为 $x$ 的方案数, $g_x$ 为连通块恰好为 $x$ 的方案数。
容易得到:
$$f_x=\sum_{i=x}^n\begin{Bmatrix}i\x\end{Bmatrix}g_i$$
其中第二类斯特林数的含义是将 $i$ 个连通块塞成 $x$ 个的方案数。至于为什么要塞成 $x$ 个,这和 $f$ 的计算方式有关,之后会提到。
那么由斯特林反演
$$g_x=\sum_{i=x}^n(-1)^{i-x}\begin{bmatrix}i\x\end{bmatrix}f_i$$
那么
$$\begin{aligned}g_1&=\sum_{i=1}^n(-1)^{i-1}\begin{bmatrix}i\1\end{bmatrix}f_i\&=\sum_{i=1}^n(-1)^{i-1}(i-1)!f_i\end{aligned}$$
考虑如何求 $f$ ,我们可以去枚举子集划分,对于横跨两个集合的边,我们必须让他们异或为 $0$ ,集合内的边可以随意连,我们不用管(这样可能会导致集合内不连通,这就是上面第二类斯特林数的含义)。
这样我们可以用 $O(bell(n))$ 的时间枚举子集划分。然后对于每一个划分,用线性基找出边集的极大线性无关组个数,记为 $tot$ ,那么在当前集合划分下方案为 $2^{s-tot}$ 。
总复杂度 $O(bell(n)s\frac{n(n-1)}{2})$ 。
Code
#include <bits/stdc++.h>
#define ll long long
using namespace std;
char ch[120];
ll t, x, bin[64], fac[64], ans, base[64], mp[64];
int s, n, belong[64];
void cal(int sz) {
t = 0; int cnt = 0;
for (int i = 0; i < 64; i++) base[i] = 0;
for (int i = 1, l = -1; i <= n; i++)
for (int j = i+1; j <= n; j++)
t |= bin[++l]*(belong[i] != belong[j]);
for (int j = 1; j <= s; j++) {
x = t&mp[j];
for (int i = 63; i >= 0; i--)
if (x&bin[i]) {
if (!base[i]) {base[i] = x; ++cnt; break; }
else x ^= base[i];
}
}
if (sz&1) ans += fac[sz-1]*bin[s-cnt];
else ans -= fac[sz-1]*bin[s-cnt];
}
void dfs(int x, int sz) {
if (x > n) {cal(sz); return; }
for (int i = 1; i <= sz+1; i++)
belong[x] = i, dfs(x+1, sz+(i == sz+1));
}
void work() {
scanf("%d", &s); bin[0] = fac[0] = 1;
for (int i = 1; i <= 10; i++) fac[i] = 1ll*fac[i-1]*i;
for (int i = 1; i < 64; i++) bin[i] = bin[i-1]<<1;
scanf("%s", ch+1);
for (int len = strlen(ch+1); n*(n-1)/2 < len; ++n);
for (int i = 1, t = 0; i <= n; i++)
for (int j = i+1; j <= n; j++)
if (ch[++t] == '1') mp[1] |= bin[t-1];
for (int T = 2; T <= s; T++) {
scanf("%s", ch+1);
for (int i = 1, t = 0; i <= n; i++)
for (int j = i+1; j <= n; j++)
if (ch[++t] == '1') mp[T] |= bin[t-1];
}
dfs(1, 0); printf("%lld\n", ans);
}
int main() {work(); return 0; }
博主蒟蒻,随意转载。但必须附上原文链接:http://www.cnblogs.com/NaVi-Awson/,否则你会终生找不到妹子!!!