Newcoder 144 C.Generation I(組合數學)
阿新 • • 發佈:2018-12-10
Description
初始有個空集編號為~,次操作,第次操作會對所有編號介於之間的集合插入一個介於之間的整數,問有多少種方案使得次操作後集合狀態不同
Input
第一行一整數表示用例組數,每組用例輸入兩個整數
Output
輸出方案數,結果模
Sample Input
2 2 2 3 4
Sample Output
Case #1: 4 Case #2: 52
Solution
最後一個集合有個數字且這個數字隨著集合編號上升依次出現的方案數為,而第一個數字必然在第個集合出現,剩下個數字只會在第個集合中依次出現,方案數,故答案為,由於,直接計算即可
Code
#include<cstdio> #include<algorithm> using namespace std; typedef long long ll; #define maxn 1000005 #define mod 998244353 int inv[maxn]; int mul(int x,int y) { ll z=1ll*x*y; return z-z/mod*mod; } int add(int x,int y) { x+=y; if(x>=mod)x-=mod; return x; } void init(int n=1e6) { inv[1]=1; for(int i=2;i<=n;i++)inv[i]=mul(mod-mod/i,inv[mod%i]); } int main() { init(); int T,Case=1; ll n,m; scanf("%d",&T); while(T--) { scanf("%lld%lld",&n,&m); int ans=m%mod; int a=m%mod,b=1; for(int i=2;i<=min(n,m);i++) { a=mul(a,(m-i+1)%mod); b=mul(b,mul((n-i+1)%mod,inv[i-1])); ans=add(ans,mul(a,b)); } printf("Case #%d: %d\n",Case++,ans); } return 0; }