[ARC061] F - Card Game for Three
首先题目可以转化为求长度为 \(n+m+k\) 的 abc 串,并且第 \(n\) 个 a 之前最多有 \(m\) 个 b 和 \(k\) 个 c。
那么直接枚举 b 和 c 是 \(O((m+k)^2)\) 的,答案为:\(\displaystyle \sum_{i=0}^m \sum_{j=0}^k 3^{m-i+k-j} \binom{n-1+i+j}{n-1} \binom{i+j}{i}\)。
尝试枚举 \(s=i+j\),那么:\(\displaystyle \sum_{s=0}^{m+k} 3^{m+k-s} \binom{n-1+s}{n-1} \sum_{j=0}^{\min \{s,m\}} \binom{s}{i}\)。
然后 \(\displaystyle \sum_{j=0}^{\min \{s,m\}} \binom{s}{i}\) 是可以递推的。
时间复杂度 \(O(n+m+k)\)。
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+9;
const int mod=1e9+7;
inline void AddAs(int &x,int y){if((x+=y)>=mod) x-=mod;}
inline void SubAs(int &x,int y){if((x-=y)<0) x+=mod;}
inline void MulAs(int &x,int y){x=1ll*x*y%mod;}
inline int Add(int x,int y){if((x+=y)>=mod) x-=mod;return x;}
inline int Sub(int x,int y){if((x-=y)<0) x+=mod;return x;}
inline int Mul(int x,int y){return 1ll*x*y%mod;}
inline int QPow(int x,int y){
int res=1;
while(y){
if(y&1) MulAs(res,x);
MulAs(x,x);
y>>=1;
}
return res;
}
#define Inv(x) QPow(x,mod-2)
int fac[N],ifac[N];
inline void InitFac(int lim){
fac[0]=1;
for(int i=1;i<=lim;i++) fac[i]=Mul(fac[i-1],i);
ifac[lim]=Inv(fac[lim]);
for(int i=lim-1;~i;i--) ifac[i]=Mul(ifac[i+1],i+1);
}
inline int C(int n,int m){
if(m>n||m<0) return 0;
else return 1ll*fac[n]*ifac[m]%mod*ifac[n-m]%mod;
}
signed main(){
int n,m,k;
cin>>n>>m>>k;
InitFac(n+m+k);
int ans=0,sum=1;
for(int s=0;s<=m+k;s++){
AddAs(ans,Mul(Mul(sum,C(n-1+s,s)),QPow(3,m+k-s)));
AddAs(sum,sum);
if(s>=m) SubAs(sum,C(s,m));
if(s>=k) SubAs(sum,C(s,s-k));
}
cout<<ans<<endl;
return 0;
}

浙公网安备 33010602011771号