[luogu p3214] [HNOI2011] 卡农
P3214 [HNOI2011] 卡农 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
在集合
- 无空集
- 选定的
个集合两两不同 - 选定的
个集合中, 到 中每个元素出现次数必为偶数。
求选定方案数。答案对
为什么不 % 1e9 + 7??为什么为什么为什么
本题最棘手的部分是第三个性质。
那么先不考虑第三个性质,只考虑前两个,容易发现一共可以有
再考虑第三个性质,发现在这种情况下,如果选定了
那么答案就是简单的
分别处理。
首先对于新的集合是空集的情况,其实就是不算新集合,前面
顺着这个继续考虑重复。如果目前要选的第
注意到,式子中的组合数事实上只限制了
总递推式:
/*
* @Author: crab-in-the-northeast
* @Date: 2022-04-22 23:37:20
* @Last Modified by: crab-in-the-northeast
* @Last Modified time: 2022-04-23 00:22:39
*/
#include <iostream>
#include <cstdio>
#define int long long // 好习惯,此处 % 葵 %%%%%%%
//但是这样我真的很烦你知道吗?int所有高亮都变成了紫色,跟 #include 一样
//无语
inline int read() {
int x = 0;
bool flag = true;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
flag = false;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + ch - '0';
ch = getchar();
}
if (flag)
return x;
return ~(x - 1);
}
const int mod = 1e8 + 7;
inline int pow(int a, int b = mod - 2) {
int s = 1;
for (; b; b >>= 1, (a *= a) %= mod)
if (b & 1)
(s *= a) %= mod;
return s;
}
signed main() {
int n = read(), m = read();
int S = pow(2, n) - 1;
int C = S * (S - 1) % mod * pow(2) % mod;
if (m <= 2) {
puts("0");
return 0;
}
int f = 0, g = 0, h = 0;
for (int i = 3; i <= m; ++i) {
f = (C - g - h * (S - i + 2 + mod) % mod + mod) % mod * pow(i) % mod;
(C *= (S - i + 1 + mod) * pow(i) % mod) %= mod;
h = g;
g = f;
}
printf("%lld\n", f);
return 0;
}
不错的题2!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】