codeforces #451E Devu and Flowers 不定方程解的个数+lucas定理

题意:链接

方法:不定方程解的个数+lucas定理

解析:

感觉做了这么多不定方程解的个数之后,每一次就是改一次组合数求法- -!

这次mod的是质数,并且观察到n,m可能大于mod,所以lucas裸上..

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 25
#define mod 1000000007 
using namespace std;
typedef long long ll;
int n;
ll s;
ll f[N]; 
ll quick_my(ll x,ll y,ll Mod)
{
    ll ret=1;
    while(y)
    {
        if(y&1)ret=(ret*x)%Mod;
        x=(x*x)%Mod;
        y>>=1;
    }
    return ret;
}
ll get_c(ll n,ll m)
{
    if(n<m)return 0;
    if(m>n-m)m=n-m;
    ll top=1,bot=1;
    for(int i=1;i<=m;i++)
    {
        top=(top*(n-i+1))%mod;
        bot=(bot*i)%mod;
    }
    return top*quick_my(bot,mod-2,mod)%mod;
} 
ll Lucas(ll n,ll m)
{
    if(m==0)return 1;
    return get_c(n%mod,m%mod)*Lucas(n/mod,m/mod)%mod;
}
ll ans;
void dfs(int now,int cnt,ll sum)
{
    if(now==n+1)
    {
        if(s-sum<0)return;
        if(cnt&1)ans=((ans-Lucas(s-sum+n-1,n-1))%mod+mod)%mod;
        else ans=(ans+Lucas(s-sum+n-1,n-1))%mod;
        return; 
    }
    dfs(now+1,cnt,sum);
    dfs(now+1,cnt+1,sum+f[now]+1);
}
int main()
{
    scanf("%d%lld",&n,&s);
    for(int i=1;i<=n;i++)scanf("%lld",&f[i]);
    dfs(1,0,0);
    printf("%lld\n",ans);
}

你可能感兴趣的:(codeforces)