Luogu P6191 [USACO09FEB]Bulls And Cows S (牡牛和牝牛)
[USACO09FEB]Bulls And Cows S
题目背景
一年一度的展会要来临了,Farmer John 想要把
题目描述
John 非常的足智多谋,他计算出任何两只公牛之间至少要有
输入格式
两个整数
输出格式
输出约翰可以安排的方法数。考虑到这个数可能很大,你只要输出对
样例 #1
样例输入 #1
4 2
样例输出 #1
6
提示
下面的就是 FJ 思考出可行的 6 种方案(C 代表奶牛,B 代表公牛):
- CCCC
- BCCC
- CBCC
- CCBC
- CCCB
- BCCB
刚开始不会写这道题,翻了翻奆佬们的题解,发现都是什么仅考虑相对位置间的关系,根本看不懂啊QAQ呜呜呜,所以诞生了我这篇相对好理解的题解
前置芝士(摘自百度文库)
题解
首先前面的部分和大部分排列组合的题解相同
设有
因此可以得到剩下的牛的数量是总的牛的数量减去公牛和母牛的数量,即
我们现在就要考虑把剩下的牛全变成奶牛插入每个公牛的空隙之间,即插入到
此时我们显然可以把问题转变为把
此时前置芝士就用到辣!!!
将前置芝士里面的
最后即可得出与其他排列组合题解相同的式子
记得特判有可能位置不够选,到
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> using namespace std; const long long mod = 5000011; long long n, k, ans = 0; long long inv[52113140], fac[52113140]; int main() { cin >> n >> k; fac[0] = fac[1] = inv[0] = inv[1] = 1; for (int i = 2; i <= mod; ++ i) { fac[i] = fac[i - 1] * i % mod; inv[i] = (mod - mod / i) * inv[mod % i] % mod; } for (int i = 2; i <= mod; ++ i) { inv[i] = inv[i - 1] * inv[i] % mod; } for (int i = 1; i <= n; ++ i) { int cow = (i - 1) * k; int remain = n - cow; if (i > remain) break; ans += (fac[remain] * inv[remain - i] % mod * inv[i]) % mod; ans %= mod; } cout << (ans + 1) % mod << endl; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】