BZOJ4671 异或图(斯特林反演+贝尔数+线性基)
题目:BZOJ4671
题目描述:
有\(s\)张含有\(n\)个点的图,选出两张图\(G_i\)和\(G_j\),将它们异或起来,就会得到一张新图\(G'\),对于新图上的一条边\((u,v)\),它存在当且仅当这条边存在于\(G_i\)和\(G_j\)中的恰好一个图上
求这\(s\)张图中有多少个子集,使得这个子集中的所有图异或起来是一张连通图
\(s \leq 60\),\(n \leq 10\)
蒟蒻题解:
发现正着推很难推,考虑容斥
最后的图是一张联通图,说明最后图中只存在一个连通块
设图中存在恰好\(i\)个连通块的方案数为\(f_i\),存在至少\(i\)个连通块的方案数为\(g_i\),那么便有:
\[g_i = \sum_{k=i}^n \begin{Bmatrix}k\\i\end{Bmatrix} f_k
\]
根据斯特林反演,我们可以得到:
\[f_i = \sum_{k=i}^n (-1)^{k-i} \begin{bmatrix}k\\i\end{bmatrix} g_k
\]
则最终答案:
\[Ans = f_1 = \sum_{k=1}^n (-1)^{k-1} \begin{bmatrix}k\\1\end{bmatrix} g_k = \sum_{k=1}^n (-1)^{k-1} (k-1)! g_k
\]
那么现在的问题就是如何求\(g_k\)
我们暴力枚举最后联通块的情况,复杂度是\(\mathcal O(B_n)\)
对于连通块的情况已知,任意一个连通块内的边是可以任意连的(这里的连通块不是真正意义上的连通块,而是至少为一个连通块,它可能可以拆分成若干个连通块),对于任意两个连通块之间不能有边相连
对于一个图,它如果连接了多个连通块,那么便把它压进线性基里面,如果它能放进去,那么便放进去,且不能选择这个图,如果它不能放进去,说明它和已放进去的图中的某一些可以异或起来,使得它不连接任意两个连通块,那么选择这个图的时候也要把那些图给异或进来,所以方案数为\(2^{n-t}\),其中\(t\)为线性基里面有值的位置数
时间复杂度为\(\mathcal O(B_nsn^2)\)
参考程序:
#include<bits/stdc++.h>
using namespace std;
#define Re register int
typedef long long ll;
const int N = 65;
int n, m, a[N];
ll ans, f[N], g[N * N];
bool G[N][N][N];
char s[N];
inline void dfs(int x, int y)
{
if (x == m)
{
int u = 0, w = 0;
for (Re i = 0; i < m - 1; ++i)
for (Re j = i + 1; j < m; ++j)
if (a[i] ^ a[j]) g[u++] = 0;
for (Re i = 0; i < n; ++i)
{
ll v = 0;
for (Re j = 0; j < m - 1; ++j)
for (Re k = j + 1; k < m; ++k)
if (a[j] ^ a[k]) v = (v << 1ll) | G[i][j][k];
if (!v) continue;
for (Re j = 0; j < u; ++j)
{
if (!((v >> j) & 1)) continue;
if (!g[j])
{
g[j] = v, ++w;
break;
}
v ^= g[j];
}
}
f[y + 1] += 1ll << (n - w);
return;
}
for (Re i = 0; i <= y + 1; ++i) a[x] = i, dfs(x + 1, i > y ? i : y);
}
int main()
{
scanf("%d", &n);
for (Re i = 0; i < n; ++i)
{
scanf("%s", s);
if (!i)
{
int len = strlen(s);
while (m * (m - 1) / 2 < len) ++m;
}
int u = 0;
for (Re j = 0; j < m - 1; ++j)
for (Re k = j + 1; k < m; ++k) G[i][j][k] = s[u++] ^ 48;
}
dfs(1, 0);
for (Re i = 1, j = 1, k = 1; i <= m; j = -j, k *= i, ++i) ans += f[i] * j * k;
printf("%lld", ans);
return 0;
}

浙公网安备 33010602011771号