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;
}
不摆烂了,写题