rt,求调。ATCoder 提交记录
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<algorithm>
#include<cassert>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<cstdlib>
using namespace std;
#define ll long long
#define ull unsigned long long
#define int ll
int read()
{
int now=0,nev=1;
char c=getchar();
while(c<'0' || c>'9')
{
if(c=='-')
nev=-1;
c=getchar();
}
while(c>='0' && c<='9')
{
now=(now<<1)+(now<<3)+(c&15);
c=getchar();
}
return now*nev;
}
const int MAXN=5e6+10;
const int mod=998244353;
const int inv2=(mod+1)/2;
int a,b,c,n;
ll fac[MAXN],inv[MAXN];
ll qpow(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1)
res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res%mod;
}
void get_fac()
{
fac[0]=1;
for(int i=1;i<=10000000;i++)
fac[i]=fac[i-1]*i%mod;
inv[10000000]=qpow(fac[10000000],mod-2);
for(int i=9999999;i>=0;i--)
inv[i]=inv[i+1]*(i+1)%mod;
}
ll C(ll n,ll m)
{
if(n<m || n<0 || m<0)
return 0;
return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int f[MAXN],g[MAXN],h[MAXN];//考虑递推快速求解球A,B,C的C(n,i)之和(i属于[0,m])
signed main()
{
n=read(),a=read(),b=read(),c=read();
get_fac();
for(int i=0;i<=a;i++)
f[n]=(f[n]+C(n,i))%mod;
for(int i=n-1;i>=0;i--)
f[i]=(f[i+1]+C(i,a))%mod*inv2%mod,cout<<f[i+1]<<endl;
for(int i=0;i<=b;i++)
g[n]=(g[n]+C(n,i))%mod;
for(int i=n-1;i>=0;i--)
g[i]=(g[i+1]+C(i,b))%mod*inv2%mod;
for(int i=0;i<=c;i++)
h[n]=(h[n]+C(n,i))%mod;
for(int i=n-1;i>=0;i--)
h[i]=(h[i+1]+C(i,c))%mod*inv2%mod;
ll ans=0;
for(int i=0;i<=n;i++)
ans=(ans+((i & 1) ? mod-1 : 1)*C(n,i)%mod*f[n-i]%mod*g[n-i]%mod*h[n-i]%mod)%mod;
printf("%lld\n",ans);
return 0;
}