题解 AT2070 【[ARC061D] 3人でカードゲーム / Card Game for Three】
command_block · · 题解
题意 : 有三堆牌,分别有
解释一下,
但糟糕的是,后半部分是一个组合数部分和,这似乎没有什么快速的方法分别求解,考虑递推。
将组合数裂开 ;
注意组合数可能不合法,此时值为
求出各个
不看题解玩出来还是有点小激动的……
#include<algorithm>
#include<cstdio>
#define ll long long
#define MaxN 900500
using namespace std;
const int mod=1000000007;
ll powM(ll a,int t=mod-2){
ll ret=1;
while(t){
if (t&1)ret=ret*a%mod;
a=a*a%mod;t>>=1;
}return ret;
}
ll fac[MaxN],ifac[MaxN];
ll C(int n,int m){
if (m<0||n<m)return 0;
return fac[n]*ifac[m]%mod*ifac[n-m]%mod;
}
void Init(int n)
{
fac[0]=1;
for (int i=1;i<=n;i++)
fac[i]=fac[i-1]*i%mod;
ifac[n]=powM(fac[n]);
for (int i=n;i;i--)
ifac[i-1]=ifac[i]*i%mod;
}
void preS(int n2,int n3,ll *S)
{
S[0]=1;
for (int k=1;k<=n2+n3;k++)
S[k]=(2*S[k-1]-C(k-1,k-1-n3)-C(k-1,n2))%mod;
}
int n1,n2,n3,N;
ll S[MaxN],pw3[MaxN];
int main()
{
scanf("%d%d%d",&n1,&n2,&n3);
Init(N=n1+n2+n3);
preS(n2,n3,S);
ll ans=0,buf=powM(3,N-n1),sav=powM(3);
for (int k=0;k<=n2+n3;k++){
ans=(ans+buf*C(n1+k-1,k)%mod*S[k])%mod;
buf=buf*sav%mod;
}printf("%lld",(ans+mod)%mod);
return 0;
}