これはライブラリがあったので簡単だった…。
https://yukicoder.me/problems/no/2572
問題
(0,0)から、右または上の格子点をたどり、(X,Y)に到達したい。
この際、以下のクエリに答えよ。
整数tが指定されるので、直線y=x+tを経由しない到達方法は何通りか。
解法
t>0の場合を考える。t<0の場合、X軸とY軸を入れ替えればよい。
Y≧X+Tの時は明らかに解0。
それ以外の場合、カタラン数の考え方を応用すると、C(X+Y,Y)-C(X+Y,Y-T)になる。
int H,W,Q; const ll mo=998244353; ll comb(ll N_, ll C_) { const int NUM_=3400001; static ll fact[NUM_+1],factr[NUM_+1],inv[NUM_+1]; if (fact[0]==0) { inv[1]=fact[0]=factr[0]=1; for (int i=2;i<=NUM_;++i) inv[i] = inv[mo % i] * (mo - mo / i) % mo; for (int i=1;i<=NUM_;++i) fact[i]=fact[i-1]*i%mo, factr[i]=factr[i-1]*inv[i]%mo; } if(C_<0 || C_>N_) return 0; return factr[C_]*fact[N_]%mo*factr[N_-C_]%mo; } ll catalan_arrange(int X,int Y,int T=1) { if(X+T<=Y) return 0; return (comb(X+Y,Y)-comb(X+Y,Y-T)+mo)%mo; } void solve() { int i,j,k,l,r,x,y; string s; cin>>H>>W>>Q; while(Q--) { int T; cin>>T; if(T>0) { cout<<catalan_arrange(H,W,T)<<endl; } else { cout<<catalan_arrange(W,H,-T)<<endl; } } }
まとめ
ライブラリにしてないともうちょい苦戦してたかも。