标签:long 表示 否则 pow 转移 mat 编号 mod 顺序
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define ll long long
#define mod 998244353
using namespace std;
string s;
ll fac[1000005],f[1005][1005],infac[1000005];
ll n,m;
ll qpow(ll a,ll b){
ll ans=1ll,res=a;
while(b){
if(b&1) ans=(ans*res)%mod;
res=(res*res)%mod;
b>>=1;
}
return ans;
}
void pre(){
ll nn=max(n,m);
// nn=min(nn,1000000);
fac[0]=1ll;
for(ll i=1;i<=nn;i++) fac[i]=fac[i-1]*i*1ll%mod;
infac[nn]=qpow(fac[nn],mod-2);
for(ll i=nn-1;i>=0;i--) infac[i]=infac[i+1]*(i+1)*1ll%mod;
// for(ll i=0;i<=nn;i++) printf("%lld ",infac[i]);
// cout<<qpow(fac[nn],2)<<endl;
// cout<<endl;
}
void work1(){
if(n<=m) printf("1\n");
else printf("0\n");
return ;
}
void work2(){//LLC
if(n<=m) printf("%lld",fac[m]*infac[m-n]%mod);
else printf("0\n");
// else if(n==m) printf("")
}
void work3(){
if(n<=m) printf("%lld",fac[m]*infac[n]%mod*infac[m-n]%mod);
else printf("0\n");
}
void work4(){//LLB
if(n<m){
printf("0\n");
return ;
}
ll ans=0;
for(ll i=0;i<=m;i++){
if(i%2==0) ans=(ans+fac[m]*infac[m-i]%mod*infac[i]%mod*qpow(m-i,n)%mod)%mod;
else ans=(ans+mod-fac[m]*infac[m-i]%mod*infac[i]%mod*qpow(m-i,n)%mod)%mod;
}
printf("%lld\n",ans);
}
void work5(){//LUB
if(n<m){
printf("0\n");
return ;
}
f[0][0]=1;
//前 i个球放在 j个盒子里的方案数
for(ll i=1ll;i<=n;i++)
for(ll j=1ll;j<=m;j++)
f[i][j]=(f[i-1][j-1]+j*f[i-1][j]%mod)%mod;
printf("%lld\n",f[n][m]);
}
void work6(){//ULB
if(n<m){
printf("0\n");
return ;
}
printf("%lld\n",fac[n-1]*infac[m-1]%mod*infac[n-m]%mod);
}
void work7(){//划分数 UUB
if(n<m){
printf("0\n");
return ;
}
f[0][0]=1ll;
for(ll i=1ll;i<=n;i++)
for(ll j=1ll;j<=m;j++)
f[i][j]=(f[i-1][j-1]+f[max(i-j,0ll)][j])%mod;
printf("%lld",f[n][m]%mod);
}
void work8(){//LLA
printf("%lld",qpow(m,n));
}
void work9(){
f[0][0]=1;
//前 i个球放在 j个盒子里的方案数
for(ll i=1ll;i<=n;i++)
for(ll j=1ll;j<=m;j++)
f[i][j]=(f[i-1][j-1]+j*f[i-1][j]%mod)%mod;
ll ans=0;
for(ll i=1;i<=m;i++)
ans=(ans+f[n][i])%mod;
printf("%lld",ans);
}
void work10(){//ULA
ll ans=0;
for(ll i=0;i<=m;i++)
ans=(ans+fac[m]*infac[i]%mod*infac[m-i]%mod*fac[n-1]%mod*infac[i-1]%mod*infac[n-i]%mod)%mod;
printf("%lld",ans);
}
void work11(){//UUA
f[0][0]=1;
ll ans=0;
for(ll i=1;i<=n;i++)
for(ll j=1;j<=m;j++)
f[i][j]=(f[i-1][j-1]+f[max(0ll,i-j)][j])%mod;
for(ll i=1;i<=m;i++) ans=(ans+f[n][i])%mod;
printf("%lld",ans);
}
int main(){
cin>>s;
scanf("%lld%lld",&n,&m);
if(n<=1000000&&m<=1000000)pre();
// cout<<s<<endl;
// printf("%lld %lld\n",n,m);
if(s=="LUC") work1();
else if(s=="LLC") work2();
else if(s=="UUC") work1();
else if(s=="ULC") work3();
else if(s=="LLB") work4();
else if(s=="LUB") work5();
else if(s=="ULB") work6();//
else if(s=="UUB") work7();
else if(s=="LLA") work8();
else if(s=="LUA") work9();
else if(s=="ULA") work10();//
else if(s=="UUA") work11();
return 0;
}
标签:long 表示 否则 pow 转移 mat 编号 mod 顺序
原文地址:https://www.cnblogs.com/Vimin/p/11777437.html