[COCI2011-2012#6] KOŠARE
Problem
有
需要选出一些箱子,要求每一种礼物至少出现在一个箱子中。
求可行的方案数
Input
输入第一行,包含正整数
接下来的
Output
输出仅一行,包含方案数
Sample
Input 1
3 3
3 1 2 3
3 1 2 3
3 1 2 3
Output 1
7
Input 2
3 3
1 1
1 2
1 3
Output 2
1
Input 3
4 5
2 2 3
2 1 2
4 1 2 3 5
4 1 2 4 5
Output 3
6
Solution
不难看出,这是一道容斥题。同时观察到
定义
最后做一个容斥,得到最后的结果。
代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int kmax = 1e6 + 3;
const int kmaxM = 23;
const int Mod = 1e9 + 7;
int n, m;
int num[kmax][kmaxM], numc[kmax];
long long f[1 << kmaxM];
long long res;
long long p[kmax];
int main() {
cin >> n >> m;
for (int i = 1, k; i <= n; i++) {
cin >> k;
int tot = 0;
for (int j = 1, x; j <= k; j++) {
cin >> x;
tot |= 1ll << (x - 1); // 排除
}
f[((1 << m) - 1) ^ tot]++;
}
for (int i = 0; i < m; i++) { // 前缀
for (int j = 0; j < 1 << m; j++) {
if (j & (1 << i)) {
f[j ^ (1 << i)] = (f[j ^ (1 << i)] + f[j]) % Mod;
}
}
}
p[0] = 1;
for (int i = 1; i < kmax; i++) { // 预处理2的次方
p[i] = p[i - 1] * 2 % Mod;
}
res = p[n];
for (int i = 1; i < 1 << m; i++) {
int tot = __builtin_popcount(i);
tot = (tot & 1 ? -1 : 1); // 容斥
res = (res + tot * p[f[i]] % Mod + Mod) % Mod;
}
cout << res;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效