题解 AT3965-[AGC025B] RGB Coloring
\(\Large\natural\) AT3965 [AGC025B] RGB Coloring / 原题链接
思路
首先,明显地,我们可以把绿色看成同时涂上红色和蓝色。这样得分仍为 \(A+B\)。
所以红色和蓝色就独立了,即它们互不影响(转化前是一个格子涂了红色就不能再涂蓝色,不是独立的)。
所以我们依次枚举红色的个数 \(i\),这样蓝色的个数就是 \(j=\frac{(K-A\times i)}{B}\)。
然后用排列组合公式来枚举会有多少种方案。即 \(C^i_n*C^j_n\)。
因为时间不紧,我用了快速幂求逆元。
代码
#include<bits/stdc++.h>
#define rep(i,x,y) for(int i=x;i<=y;i++)
#define lon long long
using namespace std;
lon mo=998244353;
lon n,a,b,ned,ans,mul[312345];
lon power(lon p,lon q){
lon tot=1;
while(q){
if(q&1)tot=(tot*p)%mo;
p=(p*p)%mo;
q=q>>1;
}
return tot;
}
lon inv(lon z){return power(z%mo,mo-2);}
lon Cnm(lon Cn,lon Cm){
if(Cn<0 || Cn>n || Cm-Cn<0)return 0;
lon upp=(mul[Cm]*inv(mul[Cm-Cn]))%mo,low=mul[Cn];
return (upp*inv(low))%mo;
}
int main(){
cin>>n>>a>>b>>ned;
mul[0]=1;
rep(i,1,n)mul[i]=(mul[i-1]*i)%mo;
rep(i,0,n){
if(ned-i*a<0)break;
if((ned-i*a)%b==0)ans=(ans+Cnm(i,n)*Cnm( (ned-i*a)/b ,n)%mo)%mo;
}
cout<<ans;
}