codeforces 145C - Lucky Subsequence mark

145C - Lucky Subsequence

题意:在一串数中任取K个数,问有几种情况是不含有两个相同的luky number

组合数计算模版,这个是超大型的组合数啊

#include<cstdio>
#include<iostream>
#include<map>
#define X 100010
#define mod 1000000007
using namespace std;
typedef long long LL;
map<int,int> g;
map<int,int>::iterator gi;
LL f[X]={1},dp[X]={1};
LL mi(LL a,LL b){
    LL as=1;
    while(b){
        if(b&1)as=(as*a)%mod;
         b>>=1;a =(a *a)%mod;
    }
    return as;
}
LL c(LL a,LL b){
    if(a<b)return 0;
    LL as=f[a];
    as=(as*mi(f[  b],mod-2))%mod;
    as=(as*mi(f[a-b],mod-2))%mod;
    return as;
}
bool luck(int x)
{
    do
    if(x%10!=4&&x%10!=7) return 0;
    while(x/=10);
    return 1;
}
int main(void)
{
     for(int i=1;i<X;i++)
        f[i]=(f[i-1]*i)%mod;
    int n,k,x;
    LL cnt=0,ans=0;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        if(luck(x))g[x]++;
        else cnt++;
    }
    int pos=1;
    for(gi=g.begin();gi!=g.end();gi++)
    {
        for(int i=min(pos,k);i>0;i--)
        {
            dp[i]+=gi->second*dp[i-1];
            dp[i]%=mod;
        }
        pos++;
    }
    pos--;
    for(int i=0;i<=pos&&i<=k;i++)
    {
        ans+=c(cnt,k-i)*dp[i];
        ans%=mod;
    }
    cout<<ans<<endl;
    return 0;
}



你可能感兴趣的:(codeforces 145C - Lucky Subsequence mark)