結果
問題 | No.2303 Frog on Grid |
ユーザー | navel_tos |
提出日時 | 2023-06-01 13:15:21 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 1,164 ms / 2,000 ms |
コード長 | 3,073 bytes |
コンパイル時間 | 200 ms |
コンパイル使用メモリ | 82,328 KB |
実行使用メモリ | 103,676 KB |
最終ジャッジ日時 | 2024-06-08 21:37:36 |
合計ジャッジ時間 | 16,765 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 77 ms
67,840 KB |
testcase_01 | AC | 91 ms
73,856 KB |
testcase_02 | AC | 1,137 ms
100,344 KB |
testcase_03 | AC | 589 ms
91,796 KB |
testcase_04 | AC | 1,136 ms
100,796 KB |
testcase_05 | AC | 1,141 ms
100,520 KB |
testcase_06 | AC | 587 ms
91,640 KB |
testcase_07 | AC | 1,160 ms
98,920 KB |
testcase_08 | AC | 1,148 ms
99,568 KB |
testcase_09 | AC | 332 ms
88,112 KB |
testcase_10 | AC | 605 ms
91,396 KB |
testcase_11 | AC | 337 ms
87,752 KB |
testcase_12 | AC | 589 ms
91,856 KB |
testcase_13 | AC | 75 ms
67,968 KB |
testcase_14 | AC | 76 ms
68,352 KB |
testcase_15 | AC | 77 ms
67,840 KB |
testcase_16 | AC | 76 ms
68,096 KB |
testcase_17 | AC | 77 ms
68,224 KB |
testcase_18 | AC | 1,164 ms
103,676 KB |
testcase_19 | AC | 1,147 ms
103,544 KB |
testcase_20 | AC | 1,160 ms
103,668 KB |
testcase_21 | AC | 1,160 ms
103,536 KB |
testcase_22 | AC | 1,154 ms
103,404 KB |
ソースコード
#yukicoder 2303 Frog on Grid #MODnCr計算機(行数削減版) class MODnCr: def __init__(self,fact_N,MOD,invN=1000): self._N=fact_N; self._invN=invN; self._MOD=MOD; self._fact=[1]*(self._N+1); self._inv=[1]*(self._invN+1); self._finv=[1]*(self._N+1) for i in range(2,self._N+1): self._fact[i]=self._fact[i-1]*i%self._MOD for i in range(2,self._invN+1): self._inv[i]=-self._inv[self._MOD%i]*(self._MOD//i)%self._MOD for i in range(2,min(self._invN,self._N)+1): self._finv[i]=self._finv[i-1]*self._inv[i]%self._MOD self._finv[self._N]=pow(self._fact[self._N],self._MOD-2,self._MOD) for i in range(self._N-1,self._invN,-1): self._finv[i]=self._finv[i+1]*(i+1)%self._MOD def _update(self,N): if N<=self._N: return 0 dist=N-self._N; self._fact.extend([1]*dist); self._finv.extend([1]*dist) for i in range(self._N+1,N+1): self._fact[i]=self._fact[i-1]*i%self._MOD self._finv[N]=self.modinv(self._fact[N]) for i in range(N-1,self._N,-1): self._finv[i]=self._finv[i+1]*(i+1)%self._MOD self._N=N; return 1 def nCr(self,n,r): if self._N<n: self._update(n) return 0 if any([n<r,n<0,r<0]) else self._fact[n]*self._finv[n-r]%self._MOD*self._finv[r]%self._MOD def modinv(self,x): return self._inv[x] if x<=self._invN else (-self._inv[self._MOD%x]*(self._MOD//x))%self._MOD if x> self._invN>=self._MOD%x else pow(x,self._MOD-2,self._MOD) #MOD = 998244353 にのみ対応したFFT。それ以外では機能しません。 class NTT_998244353: def __init__(self,MOD=998244353): self._MOD=998244353 def _FFT(self,f,fft_len,IDFT=False): h=0 while 2**h < max(len(f),fft_len): h+=1 f+=[0]*(2**h - len(f)); P=pow(3,119*2**(23-h),self._MOD) if IDFT: P=pow(P,2**h-1,self._MOD); rev=pow(2**h,self._MOD-2,self._MOD) for i in range(2**h): #バタフライ演算の並び替え j=0 for k in range(h): j|=(i>>k&1)<<(h-1-k) if i<j: f[i],f[j]=f[j],f[i] for x in range(h): b=2**x; Q=pow(P,2**(h-x-1),self._MOD); W=1 #W=Q^j for j in range(b): for k in range(0,2**h,2*b): s,t=f[j+k],f[j+k+b]*W%self._MOD; f[j+k]=(s+t)%self._MOD; f[j+k+b]=(s-t)%self._MOD W=W*Q%self._MOD if IDFT: for i in range(2**h): f[i]=f[i]*rev%self._MOD return f def convolve(self,f,g): N=1; L=len(f)+len(g)-1 while N<L: N*=2 f=self._FFT(f,N); g=self._FFT(g,N); h=[f[i]*g[i]%self._MOD for i in range(N)] return self._FFT(h,N,True)[:L] H,W=map(int,input().split()); MOD=998244353 nCr=MODnCr(4*10**5+1,MOD,2*10**5+1); NTT=NTT_998244353() DPh=[0]*(H+1); DPw=[0]*(W+1) for h in range(H+1): x=2*h-H; y=h-x; DPh[h]=nCr._finv[x]*nCr._finv[y]%MOD if 0<=x and 0<=y else 0 for w in range(W+1): x=2*w-W; y=w-x; DPw[w]=nCr._finv[x]*nCr._finv[y]%MOD if 0<=x and 0<=y else 0 DP=NTT.convolve(DPh,DPw) for i in range(1,len(DP)): DP[0]+=DP[i]*nCr._fact[i]%MOD print(DP[0]%MOD)