[ARC061] F - Card Game for Three

首先题目可以转化为求长度为 \(n+m+k\) 的 abc 串,并且第 \(n\)a 之前最多有 \(m\)b\(k\)c

那么直接枚举 bc\(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;
}
posted @ 2025-03-22 16:55  JoeyJiang  阅读(11)  评论(0)    收藏  举报