hdu 5894 hannnnah_j’s Biological Test 组合数学

传送门:hdu 5894 hannnnah_j’s Biological Test

题目大意:n个座位,m个学生,使每个学生的间隔至少为k个座位

组合中的插空法

思路:每个学生先去掉k个空位间隔,剩下n-k*m;这些空位至少要坐m个学生,n-k*m-1个空,插m-1个门,方法数为:c(n-k*m-1,m-1);当只有一个学生时,间隔K个位的条件就没必要了,也就是n>k+1的条件不一定要成立

顺带弄了个Lucas的模板

/**************************************************************
    Problem:hdu 5894 hannnnah_j’s Biological Test
    User: youmi
    Language: C++
    Result: Accepted
    Time:436MS
    Memory:17240K
****************************************************************/
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include<bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <cmath>
#include <queue>
#include <deque>
#include <string>
#include <vector>
#define zeros(a) memset(a,0,sizeof(a))
#define ones(a) memset(a,-1,sizeof(a))
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scs(a) scanf("%s",a)
#define sclld(a) scanf("%I64d",&a)
#define pt(a) printf("%d\n",a)
#define ptlld(a) printf("%I64d\n",a)
#define rep(i,from,to) for(int i=from;i<=to;i++)
#define irep(i,to,from) for(int i=to;i>=from;i--)
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define lson (step<<1)
#define rson (lson+1)
#define eps 1e-6
#define oo 0x3fffffff
#define TEST cout<<"*************************"<<endl
const double pi=4*atan(1.0);

using namespace std;
typedef long long ll;
template <class T> inline void read(T &n)
{
    char c; int flag = 1;
    for (c = getchar(); !(c >= ‘0‘ && c <= ‘9‘ || c == ‘-‘); c = getchar()); if (c == ‘-‘) flag = -1, n = 0; else n = c - ‘0‘;
    for (c = getchar(); c >= ‘0‘ && c <= ‘9‘; c = getchar()) n = n * 10 + c - ‘0‘; n *= flag;
}
ll Pow(ll base, ll n, ll mo)
{
    ll res=1;
    while(n)
    {
        if(n&1)
            res=res*base%mo;
        n>>=1;
        base=base*base%mo;
    }
    return res;
}
//***************************

ll n,m,k;
const int maxn=1000000+10;
const ll mod=1000000007;
ll fac[maxn],inver[maxn];
ll inv(ll aa)
{
    return Pow(aa,mod-2,mod);
}
void init()
{
    fac[0]=1,fac[1]=1;
    inver[0]=1,inver[1]=1;
    rep(i,2,maxn-10)
        fac[i]=fac[i-1]*i%mod,inver[i]=inver[i-1]*inv(i)%mod;
}
ll C(ll aa,ll bb)
{
    if(bb>aa)
        return 0;
    ll temp=fac[aa]*inver[bb]%mod*inver[aa-bb]%mod;
    return temp;
}
ll lucas(ll aa,ll bb)
{
    if(bb==0)
        return 1;
    return   C(aa%mod,bb%mod)*lucas(aa/mod,bb/mod)%mod;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif
    int T_T;
    scanf("%d",&T_T);
    init();
    for(int kase=1;kase<=T_T;kase++)
    {
        sclld(n),sclld(m),sclld(k);
        ll ans=lucas(n-k*m-1,m-1)*n%mod*inv(m)%mod;
        ptlld(ans);
    }
}
时间: 2024-10-11 03:59:24

hdu 5894 hannnnah_j’s Biological Test 组合数学的相关文章

HDU 5894 hannnnah_j’s Biological Test (组合数学) -2016 ICPC沈阳赛区网络赛

题目链接 题意:一个大小为 nn 的环,选 mm 个位置涂黑,要求相邻两个黑点之间至少间隔 kk 个白点,问方案数. 题解:考虑从 0 开始的标号最小的涂黑的位置,有两种情况: 如果该位置 \geq k≥k,相当于在一排(不是环) n - kn−k 个椅子里面放 mm 个人:如果该位置 < k<k, 相当于在一排 n - 2k - 1n−2k−1 个椅子里面放 (m - 1)(m−1) 个人.这种情况有 k 种. 最后考虑在一排 nn 个椅子里面放 mm 个人的方案数,相当于要找 (m + 1

HDU 5894 hannnnah_j’s Biological Test

题目链接:传送门 题目大意:有n张板凳围成一圈,有m个人,要让m个人都坐到凳子上且任意两人之间相隔>=k 个凳子,问有多少种方法%(1e9+7) 题目思路:组合数学 我们这样考虑,既然每个人相距>=k 个凳子,m个人就至少有m*k个凳子不能坐人,那我们先从中抽出这m*k个凳子,其它 凳子都可以坐了,然后我们考虑第一个人坐到了一个位置上,剩下的人就有C(n-m*k-1,m-1)种坐法,而第一个人有n种 初始选择,但由于m个人又相同,故应该是C(n-m*k-1,m-1)*n/m种坐法. Note:

HDU 5894 hannnnah_j’s Biological Test ——(组合数)

思路来自于:http://blog.csdn.net/lzedo/article/details/52585170. 不过并不需要卢卡斯定理,直接组合数就可以了. 代码如下: 1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 using namespace std; 5 typedef long long ll; 6 const int mod = (int)1e9 + 7; 7 co

hdu 5894(组合数取模)

hannnnah_j’s Biological Test Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 681    Accepted Submission(s): 235 Problem Description hannnnah_j is a teacher in WL High school who teaches biolog

排列组合+组合数取模 HDU 5894

1 // 排列组合+组合数取模 HDU 5894 2 // 题意:n个座位不同,m个人去坐(人是一样的),每个人之间至少相隔k个座位问方案数 3 // 思路: 4 // 定好m个人 相邻人之间k个座位 剩下就剩n-(m+1)*k个座位 5 // 剩下座位去插m个不同的盒子==就等价n个相同的球放m个不同的盒子 6 // 然后组合数出来了 7 // 乘n的话是枚举座位,除m是去掉枚举第一个座位的时候,剩下人相邻的座位相对不变的情况 8 9 #include <iostream> 10 #incl

2016 ACM/ICPC Asia Regional Shenyang Online 1003/HDU 5894 数学/组合数/逆元

hannnnah_j’s Biological Test Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 802    Accepted Submission(s): 269 Problem Description hannnnah_j is a teacher in WL High school who teaches biolog

HDU 4349 Xiao Ming&#39;s Hope 组合数学

题意:给你n,问在C(n,1),C(n,2)...C(n,n)中有多少个奇数. 比赛的时候打表看出规律,这里给一个数学上的说明. Lucas定理:A,B非负整数,p是质数,A,B化为p进制分别为a[n]a[n-1]...a[0],b[n]b[n-1]...b[0]. 那么组合数C(A,B)与C(a[n],b[n])*...*C(a[0],b[0])模p同余. 证明就不说了,我也不会,给个链接  Lucas定理证明 那再来看这道题就简单了,p=2,C(0,1)=0,C(1,0) = C(1,1)

HDU5894 hannnnah_j’s Biological Test 组合数取模

http://acm.hdu.edu.cn/showproblem.php?pid=5894 题意:给你n个桌子,m个人,相邻两个人之间相差至少K个桌子.问有多少种坐法. 题解:首先确定第一个人的座位,从n个座位中选择一个,然后确定出符合条件的k*m个座位.最后剩下n-1-k*m个座位,从中选出m-1个座位坐人.总数sum=n*C(n-1-k*m,m-1); 由于有m个重合,因此要sum=sum/m;例如:(2,4,7),(4,7,2),(7,2,4)是一样的. 计算组合数和sum/m时可以使用

HDU 5056 Harry And Biological Teacher

链接:http://acm.hdu.edu.cn/showproblem.php?pid=5069 题意:给出n个串,m个询问,每个询问(u,v),求u的一个最长后缀是v的前缀. 思路:离线.将关于u的后缀的查询放在一起,然后将u插入后缀自动机.对于每个v跑一遍即可. struct SAM { SAM *son[4],*pre; int len; int ok; void init() { clr(son,0); pre=0; ok=0; } }; SAM sam[N],*head,*last;