哈集幂 题解
题解
设
然后计算这个考虑单步容斥,枚举最大到达的集合,然后钦定他到不了
设
然后那么答案即为
至此,我们获得了
首先,我们发现下式是好算的,直接由
于是,我们把
直接套上模板即可。
AC_Code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i, l, r) for(int i = (l); i <= (r); i ++)
#define per(i, r, l) for(int i = (r); i >= (l); i --)
const int N = 21, M = (1 << N), E = 500, mod = 998244353;
int n, m, e[M], v, dp[N][M], f[N][M], g[M], res[M], ans, p2[E];
void add(int &x, int y){x += y;if(x >= mod)x -= mod;}
int p(int x){return __builtin_popcount(x);}
void FWT(int *a, int op){
for(int k = 1; (k << 1) <= v; k <<= 1)
for(int i = 0; i < v; i += (k << 1))
for(int j = 0; j < k; j ++){
a[i + j + k] += (a[i + j] * op + mod) % mod;
a[i + j + k] %= mod;
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n >> m;
v = 1 << n;
p2[0] = 1;
rep(i, 1, m){
p2[i] = p2[i - 1] * 2 % mod;
int u, v;
cin >> u >> v;
u --, v --;
e[(1 << u) | (1 << v)] ++;
}
FWT(e, 1);
rep(i, 0, v - 1)f[p(i)][i] = p2[e[i]];
rep(i, 0, n)FWT(f[i], 1);
rep(i, 1, n){
rep(j, 0, v - 1)g[j] = dp[i][j];
FWT(g, -1);
rep(j, 0, v - 1){
if(p(j) != i)g[j] = 0;
else g[j] = res[j] = (p2[e[j]] * (j & 1) - g[j] + mod) % mod;
}
FWT(g, 1);
rep(j, 1, n){
if(i + j > n)continue;
rep(k, 0, v - 1)add(dp[i + j][k], f[j][k] * g[k] % mod);
}
}
rep(i, (1 << n - 1) + 1, v - 1)if(i & 1)add(ans, res[i] * p2[e[(v - 1) ^ i]] % mod);
cout << ans;
return 0;
}
完结撒花。