How Many Sets II 组合数学
Time Limit: 2 Seconds Memory Limit: 65536 KB
Given a set S = {1, 2, …, n}, number m and p, your job is to count how many set T satisfies the following condition:
T is a subset of S
|T| = m
T does not contain continuous numbers, that is to say x and x+1 can not both in T
Input
There are multiple cases, each contains 3 integers n ( 1 <= n <= 109 ), m ( 0 <= m <= 104, m <= n ) and p ( p is prime, 1 <= p <= 109 ) in one line seperated by a single space, proceed to the end of file.
Output
Output the total number mod p.
Sample Input
5 1 11
5 2 11
Sample Output
5
6
Author: QU, Zhe
Contest: ZOJ Monthly, October 2011
#include
#include
using namespace std;
typedef long long ll;
ll pow(ll a,ll b,ll m)
{
ll ans=1;
a%=m;
while(b)
{
if(b&1) ans=(ans%m)*(a%m)%m;
b/=2;
a=(a%m)*(a%m)%m;
}
ans%=m;
return ans;
}
ll inv(ll x,ll p)
{
return pow(x,p-2,p);
}
ll C(ll n,ll m,ll p)
{
if(m>n) return 0;
ll up=1,down=1;
for(int i=n-m+1;i<=n;i++) up=up*i%p;
for(int i=1;i<=m;i++ ) down=down*i%p;
return up*inv(down,p)%p;
}
ll lucas(ll n,ll m, ll p)
{
if(m==0) return 1;
return C(n%p,m%p,p)*lucas(n/p,m/p,p)%p;
}
int main()
{
ll n,m,p;
while(~scanf("%lld%lld%lld",&n,&m,&p))
{
printf("%lld\n",lucas(n-m+1,m,p));
}
}