E. The Three Little Pigs 题解(组合数学+dp)

题目链接

题目大意

多组查询

计算\(\Large\sum_{i=1}^n C(3i,x)\)

题目思路

\(dp[x][m]=\sum_{i=0}^{i=n-1}C(3i+m,x)\)

\(dp[x][0]+dp[x][1]+dp[x][2]=\sum_{i=0}^{i=3n-1}C(i,x)\)

根据\(C(a,b)=C(a-1,b-1)+C(a-1,b)\)

\(\sum_{i=0}^{i=3n-1}C(i,x)=C(3n,x+1)\)

\(dp[x][0]+dp[x][1]+dp[x][2]=C(3n,x+1)\)

\(dp[x][1]=dp[x][0]+dp[x-1][0]\)

\(dp[x][2]=dp[x][1]+dp[x-1]][1]\)

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define fi first
#define se second
#define debug printf("aaaaaaaaaaa\n");
const int maxn=3e6+5,inf=0x3f3f3f3f,mod=1e9+7;
const ll INF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-7;
int n,q;
ll fac[maxn],finv[maxn];
ll dp[maxn][3];
ll qpow(ll a,ll b){
    ll ans=1,base=a;
    while(b){
        if(b&1) ans=ans*base%mod;
        base=base*base%mod;
        b=b>>1;
    }
    return ans;
}
ll c(ll a,ll b){
    return fac[a]*finv[a-b]%mod*finv[b]%mod;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>q;
    fac[0]=finv[0]=1;
    for(int i=1;i<=3*n;i++){
        fac[i]=fac[i-1]*i%mod;
    }
    finv[3*n]=qpow(fac[3*n],mod-2);
    for(int i=3*n-1;i>=1;i--){
        finv[i]=finv[i+1]*(i+1)%mod;
    }
    dp[0][0]=dp[0][1]=dp[0][2]=n;
    ll div=qpow(3,mod-2);
    for(int i=1;i<=3*n-1;i++){
        dp[i][0]=((c(3*n,i+1)-2*dp[i-1][0]-dp[i-1][1])%mod+mod)%mod*div%mod;
        dp[i][1]=(dp[i][0]+dp[i-1][0])%mod;
        dp[i][2]=(dp[i][1]+dp[i-1][1])%mod;
    }
    for(int i=1,x;i<=q;i++){
        cin>>x;
        ll ans=(dp[x][0]+c(3*n,x))%mod;
        cout<<ans<<'\n';
    }
    return 0;
}
不摆烂了,写题
原文地址:https://www.cnblogs.com/hunxuewangzi/p/15090500.html