1. 程式人生 > 實用技巧 >[LOJ6671] EntropyIncreaser 與 Minecraft - 組合數學

[LOJ6671] EntropyIncreaser 與 Minecraft - 組合數學

Description

求滿足 \(\sum_{i=1}^n |x_i| \le p\)\((x_1,x_2,...,x_n)\) 數目。\(n \le 10^6\)

Solution

列舉 \(x_k \ne 0\) 的數目 \(i\),則有

\[\sum_{i=0}^n \binom n i \binom {p-1} {i-1} 2^i =\sum_{i=0}^n \binom n i 2^i \sum_{j=i}^p \binom {j-1}{ i-1}=\sum_{i=0}^n 2^i \binom n i\binom p i \]

#include <bits/stdc++.h>
using namespace std;

#define int long long 
const int N = 1000005;
const int mod = 1e9+7;
const int dbg = 1;

int frac[N];

int qpow(int p,int q)
{
    return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;
}

int inv(int p)
{
    return qpow(p,mod-2);
}

int binom(int n,int m)
{
    if(n<m) return 0;
    return frac[n]*inv(frac[m])%mod*inv(frac[n-m])%mod;
}

signed main()
{
    ios::sync_with_stdio(false);

    int n,p;
    cin>>n>>p;

    frac[0]=1;
    for(int i=1;i<=max(n,p);i++)
    {
        frac[i]=frac[i-1]*i%mod;
    }

    int ans=0;

    for(int i=0;i<=n;i++)
    {
        ans+=qpow(2,i)*binom(n,i)%mod*binom(p,i)%mod;
        ans%=mod;
    }

    cout<<ans<<endl;
    if(dbg) system("pause");
}