NC22730. 小A的昆特牌
描述
输入描述
一行五个整数 n,m,S,l,r,含义如题目所示。
输出描述
一行一个整数,表示有多少种不同的锻造方案。
示例1
输入:
2 3 5 2 4
输出:
120
C++14(g++5.4) 解法, 执行用时: 1455ms, 内存消耗: 156880K, 提交时间: 2020-04-16 23:36:51
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int mod=998244353; const int maxn=2e7+10; int inv[maxn],A[maxn],B[maxn]; void init() { inv[0]=inv[1]=1; for(int i=2;i<maxn;++i) inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod; return; } int solve(int k,int n,int m,int S) { if(k>=S) return 0; int ans=0; A[0]=1; for(int i=1;i<n;++i) A[i]=(ll)A[i-1]*(k+i)%mod*inv[i]%mod; B[n-1]=1; for(int i=m+1,j=S-k+m;i;--i,--j) B[n-1]=(ll)B[n-1]*j%mod*inv[i]%mod; for(int i=n-2;i>=0;--i) B[i]=(ll)B[i+1]*(S-k-1+n+m-i)%mod*inv[n+m-i]%mod; for(int i=0;i<n;++i){ ans+=(ll)A[i]*B[i]%mod; if(ans>=mod) ans-=mod; } return ans; } int main() { init(); int n,m,S,l,r; scanf("%d%d%d%d%d",&n,&m,&S,&l,&r); printf("%d\n",(solve(l-1,n,m,S)-solve(r,n,m,S)+mod)%mod); return 0; }
C++11(clang++ 3.9) 解法, 执行用时: 1822ms, 内存消耗: 195984K, 提交时间: 2019-03-16 19:31:08
#include<iostream> using namespace std; const int N=2e7+10,mod=998244353; int n,m,s,l,r,inv[N],A[N],B[N]; int calc(int p) { if(p>s) return 0;int res=0; for(int i=A[0]=1;i<n;i++) A[i]=1ll*A[i-1]*(p-1+i)%mod*inv[i]%mod; for(int i=B[0]=1;i<=n+m;i++) B[i]=1ll*B[i-1]*(s-p+i)%mod*inv[i]%mod; for(int i=0;i<n;i++) (res+=1ll*A[i]*B[n+m-i]%mod)%=mod; return res; } int main() { cin>>n>>m>>s>>l>>r;inv[1]=1; for(int i=2;i<N;i++) inv[i]=mod-1ll*mod/i*inv[mod%i]%mod; cout<<(calc(l)-calc(r+1)+mod)%mod<<endl; }