我是靠谱客的博主 勤奋指甲油,最近开发中收集的这篇文章主要介绍hdu-5894-hannnnah_j’s Biological Test(Lucas定理+乘法逆+组合数),觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
hannnnah_j’s Biological Test
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Problem Description
hannnnah_j is a teacher in WL High school who teaches biology.
One day, she wants to test m students, thus she arranges n different seats around a round table.
In order to prevent cheating, she thinks that there should be at least k empty seats between every two students.
hannnnah_j is poor at math, and she wants to know the sum of the solutions.So she turns to you for help.Can you help her? The answer maybe large, and you need to mod 1e9+7.
Input
First line is an integer T(T≤1000).
The next T lines were given n, m, k, respectively.
0 < m < n < 1e6, 0 < k < 1000
Output
For each test case the output is only one integer number ans in a line.
Sample Input
2
4 2 6
5 2 1
Sample Output
0
5
题意:
给一个m个学生在长度为n的环形摆放的座位安排座位,要求相邻两个学生座位之间的距离至少是k,交换两个学生后的摆放和原来一样视为同种方案,求总方案数%1e9+7。
题目链接:hannnnah_j’s Biological Test
解题思路:
先从n个座位选一个出来,符合条件的方案,必须有k*m个空座位,那么接下来只需从n-1+k*m个座位中选出m-1个同
学的座位即可,第一个位置有n种选法,但因为学生都是一样的,同种方案会被不同的学生选到,即选了m次,删去重
复答案为n*C(n-k*m-1, m-1)/m % (1e9+7)。
计算组合数取模可以套用Lucas模板,在模mod下,a/b %mod 与 a*(b)的逆 同余数,用inv(m,mod)求解模mod下m的
逆(Lrj 训练指南122)。
代码:
#include<cstdio>
using namespace std;
typedef long long LL;
const int N = 1e6+5;
const LL mod = 1e9+7;
LL fac[N+10];
LL pow_mod(LL x, LL n)//快速幂取模
{
LL sum = 1;
while(n) {
if(n & 1) sum = sum * x % mod;
x = x * x % mod;
n >>= 1;
}
return sum;
}
void init()//初始化所需要的阶乘
{
fac[0] = 1;
for(int i = 1;i <= N;i++)
fac[i] =fac[i-1] * i % mod;
}
LL Lucas(LL n, LL m)//Lucas定理,计算C(n,m)%mod
{
LL ans = 1;
while(n && m) {
LL a = n % mod, b = m % mod;
if(a < b) return 0;
ans = ans * fac[a] * pow_mod(fac[b]*fac[a-b] % mod, mod-2) % mod;
n /= mod;
m /= mod;
}
return ans;
}
void exd_gcd(LL a, LL b, LL& d, LL& x, LL& y)//拓展欧几里得解方程ax+by=gcd(a,b);
{
if(!b) {
d = a;
x = 1;
y = 0;
}
else {
exd_gcd(b, a%b, d, y, x);
y -= x*(a/b);
}
}
LL inv(LL a, LL n)//计算模n下a的逆元,如果不存在,返回-1
{
LL d, x, y;
exd_gcd(a, n, d, x, y);
return d == 1? (x+n)%n : -1;
}
int main()
{
int T;
LL n, m, k;
init();
scanf("%d",&T);
while(T--) {
scanf("%I64d%I64d%I64d",&n, &m, &k);
if(m == 1) {
printf("%I64dn",n);
continue;
}
printf("%I64dn",(n * Lucas(n-k*m-1, m-1) % mod) * inv(m, mod) % mod);
}
return 0;
}
最后
以上就是勤奋指甲油为你收集整理的hdu-5894-hannnnah_j’s Biological Test(Lucas定理+乘法逆+组合数)的全部内容,希望文章能够帮你解决hdu-5894-hannnnah_j’s Biological Test(Lucas定理+乘法逆+组合数)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复