「解题报告」CF1292F Nora's Toy Boxes
好厉害。
首先发现一件事情,就是假如存在一个
正着考虑不好考虑,我们可以反过来考虑,假如最后剩下了某个集合,那么每次操作就相当于将一个与
那么我们现在就有一个朴素的做法,考虑大力状压,设
此时我们考虑的是
分析
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 66, P = 1000000007;
int n, m, k;
int a[MAXN];
bool in[MAXN];
int id[MAXN];
int to[MAXN];
int f[1 << 15][MAXN];
int cnt[1 << 15];
vector<int> e[MAXN];
bool vis[MAXN];
vector<int> pt;
void dfs(int u) {
vis[u] = 1;
m++, k += in[u];
if (in[u]) id[u] = k - 1;
pt.push_back(u);
for (int v : e[u]) if (!vis[v]) {
dfs(v);
}
}
int C[MAXN][MAXN];
int main() {
scanf("%d", &n);
C[0][0] = 1;
for (int i = 1; i <= n; i++) {
C[i][0] = 1;
for (int j = 1; j <= i; j++) {
C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % P;
}
}
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
}
for (int i = 1; i <= n; i++) {
bool flag = true;
for (int j = 1; j <= n; j++) if (j != i) {
if (a[i] % a[j] == 0) {
flag = false;
break;
}
}
if (flag) {
in[i] = 1;
}
}
for (int i = 1; i <= n; i++) if (!in[i]) {
for (int j = 1; j <= n; j++) if (i != j && in[j]) {
if (a[i] % a[j] == 0) {
e[i].push_back(j), e[j].push_back(i);
}
}
}
int tot = 0, ans = 1;
for (int rt = 1; rt <= n; rt++) if (!vis[rt]) {
m = k = 0;
pt.clear();
dfs(rt);
if (m == k) continue;
for (int s = 0; s < (1 << k); s++) {
cnt[s] = 0;
for (int i = 0; i <= m - k; i++) f[s][i] = 0;
}
for (int i : pt) if (!in[i]) {
for (int j : pt) if (i != j && in[j]) {
if (a[i] % a[j] == 0) {
to[i] |= 1 << id[j];
}
}
cnt[to[i]]++;
}
for (int mid = 1; mid < (1 << k); mid <<= 1) {
for (int l = 0; l < (1 << k); l += (mid << 1)) {
for (int i = 0; i < mid; i++) {
cnt[l + i + mid] += cnt[l + i];
}
}
}
for (int i : pt) if (!in[i]) {
f[to[i]][1]++;
}
for (int s = 1; s < (1 << k); s++) {
for (int i = 1; i <= m - k; i++) if (f[s][i]) {
f[s][i + 1] = (f[s][i + 1] + 1ll * f[s][i] * (cnt[s] - i)) % P;
for (int j : pt) if (!in[j] && (to[j] & s) != 0 && ((to[j] | s) != s)) {
f[s | to[j]][i + 1] = (f[s | to[j]][i + 1] + f[s][i]) % P;
}
}
}
ans = 1ll * ans * f[(1 << k) - 1][m - k] % P * C[tot + m - k - 1][m - k - 1] % P;
tot += m - k - 1;
}
printf("%d\n", ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通