xyd 好题分享1
ARC061F 3人でカードゲーム
三人 𝑎,𝑏,𝑐 面前分别有 \(n_1,n_2,n_3\) 张牌, 每张牌上写了 𝑎,𝑏,𝑐 中的一个, 规则如下:
第一回合是 𝑎 的回合,若轮到某个玩家行动时他面前没牌了,该玩家获胜。
否则拿出牌堆中的一张牌,丢掉它,并进入该牌上写着的玩家的回合 游戏开始前牌的所有情况共 \(3^{𝑛_1+n_2+n_3}\) 种
求 𝑎 获胜的情况数对 \(10^9+7\) 取模。
\(a,b,c\le 3\times 10^5\)
考虑对每一个用牌数 \(k\) 进行求解,首先一定有 \(n_1\) 张 \(a\),且最后一张用的牌一定是一,牌 \(b,c\) 数量小于等于 \(n_2,n_3\),所以分配的方案有
\[3^{n_2+n_3-k}\binom{k+n_1-1}{k}\sum\limits_{i\in[k-n_3,n_2]}\binom{k}{i}
\]
将后面那一坨拎出来 DP。设 \(f(k)=\sum\limits_{i\in[k-n_3,n_2]}\binom{k}{i}\),则有
\[\begin{aligned}
f(k)&=\sum\limits_{i\in[k-n_3,n_2]}\binom{k-1}{i}+\binom{k-1}{i-1}\\
&=\sum\limits_{i\in[k-n_3,n_2]}\binom{k-1}{i}+\sum\limits_{i\in[k-n_3,n_2]}\binom{k-1}{i-1}\\
&=\sum\limits_{i\in[k-1-n_3,n_2]}\binom{k-1}{i}-\binom{k-1}{k-1-n_3}+\sum\limits_{i\in[k-1-n_3,n_2-1]}\binom{k-1}{i}\\
&=\sum\limits_{i\in[k-1-n_3,n_2]}\binom{k-1}{i}-\binom{k-1}{k-1-n_3}+\sum\limits_{i\in[k-1-n_3,n_2]}\binom{k-1}{i}-\binom{k-1}{n_2}\\
&=2f(k-1)-\binom{k-1}{k-1-n_3}-\binom{k-1}{n_2}
\end{aligned}\]
直接递推即可。最后答案为
\[\sum\limits_{k=0}^{n_2+n_3}3^{n_2+n_3-k}\binom{k+n_1-1}{k}f(k)
\]
时间复杂度 \(O(n_1+n_2+n_3)\)。
点击查看代码
#include<bits/stdc++.h>
#define int long long
const int maxn=1e6+3;
const int mod=1e9+7;
using namespace std;
int f[maxn],n1,n2,n3;
int invf[maxn],fac[maxn],f3n[maxn];
int qpow(int a,int b){
int res=1;
for(;b;b>>=1,a=a*a%mod) if(b&1) res=res*a%mod;
return res;
}
int C(int a,int b){
if(a<b) return 0;
if(b<0) return 0;
return fac[a]*invf[a-b]%mod*invf[b]%mod;
}
signed main(){
cin>>n1>>n2>>n3;
fac[0]=f3n[0]=1;
for(int i=1;i<=n1+n2+n3;i++){
fac[i]=fac[i-1]*i%mod;
f3n[i]=f3n[i-1]*3%mod;
}
invf[n1+n2+n3]=qpow(fac[n1+n2+n3],mod-2);
for(int i=n1+n2+n3-1;~i;i--)
invf[i]=invf[i+1]*(i+1)%mod;
f[0]=1;
for(int i=1;i<=n2+n3;i++)
f[i]=(2*f[i-1]%mod-C(i-1,i-n3-1)-C(i-1,n2)+mod+mod)%mod;
int ans=0;
for(int i=0;i<=n2+n3;i++)
ans=(ans+f3n[n2+n3-i]*C(i+n1-1,i)%mod*f[i]%mod)%mod;
cout<<ans;
return 0;
}