社区讨论
求助卡常
P11567建造军营 II参与者 3已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @mlk6awwz
- 此快照首次捕获于
- 2026/02/13 08:52 4 周前
- 此快照最后确认于
- 2026/02/15 19:40 3 周前
rt,不知道为啥特别慢,目前查出来主要要卡子集卷积和 exp 的部分,但是感觉没啥能卡的了,不知道是不是我封装的问题。
代码:
CPP#include <bits/stdc++.h>
using namespace std;
const int maxn = 17, N = (1 << 16) + 5, mod = 1e9 + 7;
inline int add(int x, int y) {
x += y;
return (x >= mod ? x % mod : x);
}
struct Poly {
vector<int> a;
inline void resize(int N) {
a.resize(N);
}
inline int size() {
return a.size();
}
inline int& operator[](int x) {
return a[x];
}
inline void clear() {
a.clear();
}
inline auto begin() {
return a.begin();
}
inline auto end() {
return a.end();
}
inline void fwt(int f) {
int n = size();
for (int h = 2; h <= n; h <<= 1)
for (int i = 0; i < n; i += h)
for (int j = i; j < i + h / 2; j++)
a[j + h / 2] = add(1ll * a[j] * f % mod, a[j + h / 2]);
}
inline friend Poly operator+(Poly f, Poly g) {
int n = f.size();
for (int i = 0; i < n; i++)
f[i] = (f[i] + g[i]) % mod;
return f;
}
} tf[maxn], tg[maxn], th[maxn];
int cnt[N];
inline Poly operator*(Poly &f, Poly &g) {
int n = f.size(), l = 0;
for (l = 0; (1 << l) <= n; l++) {
fill(tf[l].begin(), tf[l].end(), 0);
fill(tg[l].begin(), tg[l].end(), 0);
fill(th[l].begin(), th[l].end(), 0);
}
for (int i = 0; i < n; i++)
tf[cnt[i]][i] = f[i], tg[cnt[i]][i] = g[i];
for (int i = 0; i < l; i++)
tf[i].fwt(1), tg[i].fwt(1);
// cout << "adsf" << endl;
for (int i = 0; i < l; i++)
for (int j = 0; j < l; j++)
if(i + j < l) {
for (int k = 0; k < n; k++)
th[i + j][k] = add(th[i + j][k], 1ll * tf[i][k] * tg[j][k] % mod);
}
for (int i = 0; i < l; i++)
th[i].fwt(mod - 1);
for (int i = 0; i < n; i++)
f[i] = th[cnt[i]][i];
//cout << "adf" << endl;
return f;
}
int inv[maxn];
Poly get_s_exp(Poly &f) {
Poly ans; ans.resize(f.size());
ans[0] = 1;
for (int i = 1; i < f.size(); i++) {
for (int j = 1; j <= i; j++)
ans[i] = add(ans[i], 1ll * j * f[j] % mod * ans[i - j] % mod);
ans[i] = 1ll * ans[i] * inv[i] % mod;
}
return ans;
}
Poly get_exp(Poly &f) {
int n = f.size(), l = 0;
for (l = 0; (1 << l) <= n; l++)
fill(tf[l].begin(), tf[l].end(), 0);
//cout << l << "adf" << endl;
for (int i = 0; i < n; i++)
tf[cnt[i]][i] = f[i];
for (int i = 0; i < l; i++)
tf[i].fwt(1);
Poly t; t.resize(l);
for (int i = 0; i < n; i++) {
for (int j = 0; j < l; j++)
t[j] = tf[j][i];
t = get_s_exp(t);
for (int j = 0; j < l; j++)
tf[j][i] = t[j];
}
for (int i = 0; i < l; i++)
tf[i].fwt(mod - 1);
for (int i = 0; i < n; i++)
f[i] = tf[cnt[i]][i];
return f;
}
int n, msk[maxn], m;
int cal(int S, int T) {
int ans = 0;
for (int i = 1; i <= n; i++)
ans += ((S >> i - 1) & 1) * cnt[msk[i] & T];
return ans;
}
Poly tp;
int pw[maxn * maxn], e[N];
#define lowbit(x) (x & (-x))
Poly Trans(Poly f, int coef) {
tp.resize(1 << n);
for (int i = n; i >= 1; i--) {
// cout << i << endl;
for (int j = 0; j < (1 << n); j++)
tp[j] = ((j & (1 << i - 1)) ? 0 : 1ll * f[j] % mod * cal(j & ((1 << i) - 1), 1 << i - 1) % mod * coef % mod);
tp = get_exp(tp);
tp = tp * f;
// for (int j = 0; j < (1 << n); j++)
// cout << f[j] << " ";
// cout << endl;
for (int j = 0; j < (1 << n); j++)
f[j] = ((j & (1 << i - 1)) ? tp[j] : f[j]);
}
return f;
}
int k, a[maxn * 3], b[maxn * 3], edge[maxn][maxn], pw2[maxn * maxn], pw3[maxn * maxn];
signed main() {
cin >> n >> k;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
char c = getchar();
while(!isdigit(c))
c = getchar();
edge[i][j] = c - '0';
msk[i] |= edge[i][j] << j - 1;
}
for (int i = 1; i <= k; i++)
cin >> a[i] >> b[i];
for (int i = 1; i < (1 << n); i++)
cnt[i] = cnt[i >> 1] + (i & 1);
inv[1] = 1;
for (int i = 2; i <= n; i++)
inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod;
for (int i = 0; i < (1 << n); i++)
e[i] = cal(i, i) / 2;
Poly f, g; g.resize((1 << n)), f.resize((1 << n));
pw2[0] = pw3[0] = 1;
for (int i = 1; i <= n * n; i++)
pw2[i] = pw2[i - 1] * 2 % mod;
for (int i = 1; i <= n * n; i++)
pw3[i] = pw3[i - 1] * 3 % mod;
for (int i = 0; i <= n; i++)
tf[i].resize((1 << n)),
tg[i].resize(1 << n),
th[i].resize(1 << n);
for (int i = 0; i < (1 << n); i++) {
f[i] = pw2[e[i]]; g[i] = pw3[e[i]];
// cout << f[i] << endl;
for (int s = i; s; s = (s - 1) & i)
if(lowbit(s) == lowbit(i) && s != i)
f[i] = add(f[i], mod - 1ll * f[s] * pw2[e[s ^ i]] % mod),
g[i] = add(g[i], mod - 1ll * g[s] * pw3[e[s ^ i]] % mod);
// cout << i << " " << f[i] << " " << g[i] << endl;
}
for (int i = 0; i < (1 << n); i++) {
for (int j = 1; j <= k; j++) {
int cnt = ((i >> a[j] - 1) & 1) + ((i >> b[j] - 1) & 1);
if(cnt == 1)
f[i] = 0;
}
}
f = Trans(f, mod - 1); g = Trans(g, mod - 2);
for (int i = 0; i < (1 << n); i++) {
int cnt = 0;
for (int j = 1; j <= k; j++)
cnt += ((i >> a[j] - 1) & 1) + ((i >> b[j] - 1) & 1);
if(!cnt)
f[i] = g[i];
}
f = Trans(f, 2);
cout << f[(1 << n) - 1] << endl;
return 0;
}
/*
3 0
011
101
110
*/
回复
共 2 条回复,欢迎继续交流。
正在加载回复...