爱丽丝的人偶(二)
B题链接:https://ac.nowcoder.com/acm/contest/8755/B
爱丽丝有个人偶,第 个人偶的型号为。
现在爱丽丝要拿出其中个人偶,满足这个人偶的型号互不相同。
爱丽丝想知道自己有多少多不同的方案数?
注:若两个人偶的型号相同,那么无论拿她们中的哪一个都是等价的。
请将方案数对取模。
输入描述:
第一行输入两个正整数和,用空格隔开。
第二行输入个正整数,代表这个人偶的型号。
输出描述:
一个整数,代表最终方案的数量对取模的值。
示例1
输入
5 2
1 2 3 2 1
输出
3
说明
一共有{1,2}{1,3}{2,3}这三种不同的方案(型号组合)。
请注意,拿第一个和第三个、第三个和第五个最终的型号组合都是{1,3},被视为同一种方案。
题目描述:求 C n m
思路:先算出该怎么计算就怎么算,比如 C 6 2 ,就先算出6∗5,然后再算出1∗2,那么答案不就是30 / 2吗。因为这个地方算出的结果可能很大,所以要在算的过程中不断地取模,而且这个让取模的数是个大素数,所以可以通过乘法逆元来求出最终答案,a/b%mod = a * b^(mod -2) % mod ,这个可以通过快速幂迅速求出来。
其实一开始我只想到了组合数,没想过b^(mod -2),没搞弄原理。
正确代码:
#include<iostream>
#include<stdio.h>
#include<map>
using namespace std;
long long qmi(long long a,long long b)
{
long long res = 1;
while(b){
if(b & 1) res = res * a % (1000000000+7);
a = a * a % (1000000000+7);
b = b >> 1;
}
return res;
}
int main(){
long long n,k;
while(cin>>n>>k){
map<long long,int>mp;
long long ans=0;
long long b=1;
for(int i=0;i<n;i++){
long long a;
cin>>a;
if(mp[a]==0){
mp[a]++;
ans++;
//ans=ans%(10000000000+7)+1;
}
}
if(k<=ans&&ans>0){
long long a=1;
for(int i=ans-k+1;i<=ans;i++){
b=b*i%(1000000000+7);
}
for(int i=1;i<=k;i++){
a=a*i%(1000000000+7);
}
cout<<(b*qmi(a,1000000000+7 - 2))%(1000000000+7)<<endl;
}
else{
cout<<"0"<<endl;
}
}
return 0;
}