洛谷——爱丽丝的人偶(二)

爱丽丝的人偶(二)

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
#include
#include
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;
}

你可能感兴趣的:(#,模拟,牛客网)