【题目描述】
商店里出售n种花,现打算购买m支花,每种花最多购买1支,询问有多少种购买方案,输出方案数 mod p的值。
【输入描述】
输入三个整数n、m、p。
【输出描述】
输出一个整数,表示答案。
【输入样例】
4 2 5
【输出样例】
1
【数据范围及提示】
样例中,若用数字1、2、3、4来表示花的种类,4种花里购买各不相同的2支的方案有(1,2)、(1,3)、(1,4)、(2,3)、(2,4)、(3,4),共6种方案,模5后为1。
对于30%的数据,n,m ≤ 10;
对于50%的数据,n,m ≤ 1000;
对于80%的数据,1 ≤ m ≤n ≤ 50000;
对于100%的数据,1 ≤ m ≤ n ≤ 1000000,p ≤ 1000000000。
源代码: #include<cstdio> #include<cmath> #define LL long long LL m,n,INF,Num(0),Ans=1,Sum[350000]={0},Prime[350000]; bool Vis[1000001]={0}; LL Count(LL S,LL X) { LL Number=1; while (S) { if (S&1) Number=Number*X%INF; X=X*X%INF; S>>=1; } return Number; } void Euler() { LL t=n; for (LL a=2;a<=t;a++) { if (!Vis[a]) Prime[Num++]=a; for (LL b=0;b<Num&&a*Prime[b]<=t;b++) { Vis[a*Prime[b]]=true; if (!(a%Prime[b])) break; } } } int main() //老办法。 { scanf("%lld%lld%lld",&n,&m,&INF); Euler(); for (LL a=0;a<Num;a++) { LL t=n; while (t) { Sum[a]+=t/Prime[a]; t/=Prime[a]; } } n-=m; for (LL a=0;a<Num;a++) { LL t=n; while (t) { Sum[a]-=t/Prime[a]; t/=Prime[a]; } } for (LL a=0;a<Num;a++) { LL t=m; while (t) { Sum[a]-=t/Prime[a]; t/=Prime[a]; } } for (LL a=0;a<Num;a++) if (Sum[a]) Ans=Count(Sum[a],Prime[a])%INF*Ans%INF; printf("%lld",Ans); return 0; }