結果
問題 | No.2231 Surprising Flash! |
ユーザー | chineristAC |
提出日時 | 2023-09-27 14:09:29 |
言語 | PyPy3 (7.3.15) |
結果 |
TLE
|
実行時間 | - |
コード長 | 18,154 bytes |
コンパイル時間 | 216 ms |
コンパイル使用メモリ | 82,304 KB |
実行使用メモリ | 272,360 KB |
最終ジャッジ日時 | 2024-07-20 08:13:27 |
合計ジャッジ時間 | 43,171 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 115 ms
87,552 KB |
testcase_01 | AC | 170 ms
88,832 KB |
testcase_02 | AC | 436 ms
92,544 KB |
testcase_03 | AC | 621 ms
97,300 KB |
testcase_04 | AC | 434 ms
92,836 KB |
testcase_05 | AC | 123 ms
88,192 KB |
testcase_06 | AC | 634 ms
97,544 KB |
testcase_07 | AC | 188 ms
90,288 KB |
testcase_08 | AC | 303 ms
92,228 KB |
testcase_09 | AC | 138 ms
88,960 KB |
testcase_10 | AC | 120 ms
87,808 KB |
testcase_11 | AC | 151 ms
96,896 KB |
testcase_12 | AC | 162 ms
100,096 KB |
testcase_13 | AC | 1,277 ms
270,288 KB |
testcase_14 | AC | 1,163 ms
237,540 KB |
testcase_15 | AC | 148 ms
96,620 KB |
testcase_16 | AC | 1,044 ms
199,996 KB |
testcase_17 | AC | 1,083 ms
206,968 KB |
testcase_18 | AC | 1,435 ms
269,768 KB |
testcase_19 | AC | 1,422 ms
272,360 KB |
testcase_20 | AC | 1,459 ms
268,928 KB |
testcase_21 | AC | 1,439 ms
269,960 KB |
testcase_22 | AC | 1,478 ms
270,060 KB |
testcase_23 | AC | 1,457 ms
261,928 KB |
testcase_24 | AC | 1,418 ms
266,524 KB |
testcase_25 | AC | 1,412 ms
267,860 KB |
testcase_26 | AC | 1,429 ms
269,296 KB |
testcase_27 | AC | 1,451 ms
268,528 KB |
testcase_28 | AC | 1,416 ms
269,124 KB |
testcase_29 | AC | 1,611 ms
268,960 KB |
testcase_30 | AC | 1,554 ms
269,240 KB |
testcase_31 | AC | 1,600 ms
271,152 KB |
testcase_32 | AC | 1,575 ms
267,328 KB |
testcase_33 | AC | 1,549 ms
270,072 KB |
testcase_34 | AC | 153 ms
96,780 KB |
testcase_35 | AC | 152 ms
96,768 KB |
testcase_36 | AC | 146 ms
96,644 KB |
testcase_37 | AC | 150 ms
96,768 KB |
testcase_38 | AC | 152 ms
97,024 KB |
testcase_39 | AC | 780 ms
164,096 KB |
testcase_40 | AC | 637 ms
146,336 KB |
testcase_41 | AC | 114 ms
88,172 KB |
testcase_42 | AC | 115 ms
87,952 KB |
testcase_43 | AC | 115 ms
87,704 KB |
testcase_44 | TLE | - |
ソースコード
mod = 998244353 omega = pow(3,119,mod) rev_omega = pow(omega,mod-2,mod) N = 2*10**5 g1 = [1]*(N+1) # 元テーブル g2 = [1]*(N+1) #逆元テーブル inv = [1]*(N+1) #逆元テーブル計算用テーブル for i in range( 2, N + 1 ): g1[i]=( ( g1[i-1] * i ) % mod ) inv[i]=( ( -inv[mod % i] * (mod//i) ) % mod ) g2[i]=( (g2[i-1] * inv[i]) % mod ) inv[0]=0 def _ntt(f,L,reverse=False): F=[f[i] for i in range(L)] n = L.bit_length() - 1 base = omega if reverse: base = rev_omega if not n: return F size = 2**n wj = pow(base,2**22,mod) res = [0]*2**n for i in range(n,0,-1): use_omega = pow(base,2**(22+i-n),mod) res = [0]*2**n size //= 2 w = 1 for j in range(0,L//2,size): for a in range(size): res[a+j] = (F[a+2*j] + w * F[a+size+2*j]) % mod t = (w * wj) % mod res[L//2+a+j] = (F[a+2*j] + t * F[a+size+2*j]) % mod w = (w * use_omega) % mod F = res return res def ntt(f,L=0): l = len(f) if not L: L = 1<<((l-1).bit_length()) while len(f)<L: f.append(0) f=f[:L] F = _ntt(f,L) return F def intt(f,L=0): l = len(f) if not L: L = 1<<((l-1).bit_length()) while len(f)<L: f.append(0) f=f[:L] F = _ntt(f,L,reverse=True) inv = pow(L,mod-2,mod) for i in range(L): F[i] *= inv F[i] %= mod return F def convolve(_f,_g,limit): f = [v for v in _f] g = [v for v in _g] l = len(f)+len(g)-1 L = 1<<((l-1).bit_length()) F = ntt(f,L) G = ntt(g,L) H = [(F[i] * G[i]) % mod for i in range(L)] h = intt(H,L) return h[:limit] mod = 998244353 omega = pow(3,119,mod) rev_omega = pow(omega,mod-2,mod) N = 2*10**5 g1 = [1]*(N+1) # 元テーブル g2 = [1]*(N+1) #逆元テーブル inv = [1]*(N+1) #逆元テーブル計算用テーブル for i in range( 2, N + 1 ): g1[i]=( ( g1[i-1] * i ) % mod ) inv[i]=( ( -inv[mod % i] * (mod//i) ) % mod ) g2[i]=( (g2[i-1] * inv[i]) % mod ) inv[0]=0 _fft_mod = 998244353 _fft_imag = 911660635 _fft_iimag = 86583718 _fft_rate2 = (911660635, 509520358, 369330050, 332049552, 983190778, 123842337, 238493703, 975955924, 603855026, 856644456, 131300601, 842657263, 730768835, 942482514, 806263778, 151565301, 510815449, 503497456, 743006876, 741047443, 56250497, 867605899) _fft_irate2 = (86583718, 372528824, 373294451, 645684063, 112220581, 692852209, 155456985, 797128860, 90816748, 860285882, 927414960, 354738543, 109331171, 293255632, 535113200, 308540755, 121186627, 608385704, 438932459, 359477183, 824071951, 103369235) _fft_rate3 = (372528824, 337190230, 454590761, 816400692, 578227951, 180142363, 83780245, 6597683, 70046822, 623238099, 183021267, 402682409, 631680428, 344509872, 689220186, 365017329, 774342554, 729444058, 102986190, 128751033, 395565204) _fft_irate3 = (509520358, 929031873, 170256584, 839780419, 282974284, 395914482, 444904435, 72135471, 638914820, 66769500, 771127074, 985925487, 262319669, 262341272, 625870173, 768022760, 859816005, 914661783, 430819711, 272774365, 530924681) def _butterfly(a): n = len(a) h = (n - 1).bit_length() len_ = 0 while len_ < h: if h - len_ == 1: p = 1 << (h - len_ - 1) rot = 1 for s in range(1 << len_): offset = s << (h - len_) for i in range(p): l = a[i + offset] r = a[i + offset + p] * rot % _fft_mod a[i + offset] = (l + r) % _fft_mod a[i + offset + p] = (l - r) % _fft_mod if s + 1 != (1 << len_): rot *= _fft_rate2[(~s & -~s).bit_length() - 1] rot %= _fft_mod len_ += 1 else: p = 1 << (h - len_ - 2) rot = 1 for s in range(1 << len_): rot2 = rot * rot % _fft_mod rot3 = rot2 * rot % _fft_mod offset = s << (h - len_) for i in range(p): a0 = a[i + offset] a1 = a[i + offset + p] * rot a2 = a[i + offset + p * 2] * rot2 a3 = a[i + offset + p * 3] * rot3 a1na3imag = (a1 - a3) % _fft_mod * _fft_imag a[i + offset] = (a0 + a2 + a1 + a3) % _fft_mod a[i + offset + p] = (a0 + a2 - a1 - a3) % _fft_mod a[i + offset + p * 2] = (a0 - a2 + a1na3imag) % _fft_mod a[i + offset + p * 3] = (a0 - a2 - a1na3imag) % _fft_mod if s + 1 != (1 << len_): rot *= _fft_rate3[(~s & -~s).bit_length() - 1] rot %= _fft_mod len_ += 2 def _butterfly_inv(a): n = len(a) h = (n - 1).bit_length() len_ = h while len_: if len_ == 1: p = 1 << (h - len_) irot = 1 for s in range(1 << (len_ - 1)): offset = s << (h - len_ + 1) for i in range(p): l = a[i + offset] r = a[i + offset + p] a[i + offset] = (l + r) % _fft_mod a[i + offset + p] = (l - r) * irot % _fft_mod if s + 1 != (1 << (len_ - 1)): irot *= _fft_irate2[(~s & -~s).bit_length() - 1] irot %= _fft_mod len_ -= 1 else: p = 1 << (h - len_) irot = 1 for s in range(1 << (len_ - 2)): irot2 = irot * irot % _fft_mod irot3 = irot2 * irot % _fft_mod offset = s << (h - len_ + 2) for i in range(p): a0 = a[i + offset] a1 = a[i + offset + p] a2 = a[i + offset + p * 2] a3 = a[i + offset + p * 3] a2na3iimag = (a2 - a3) * _fft_iimag % _fft_mod a[i + offset] = (a0 + a1 + a2 + a3) % _fft_mod a[i + offset + p] = (a0 - a1 + a2na3iimag) * irot % _fft_mod a[i + offset + p * 2] = (a0 + a1 - a2 - a3) * irot2 % _fft_mod a[i + offset + p * 3] = (a0 - a1 - a2na3iimag) * irot3 % _fft_mod if s + 1 != (1 << (len_ - 1)): irot *= _fft_irate3[(~s & -~s).bit_length() - 1] irot %= _fft_mod len_ -= 2 def _convolution_naive(a, b): n = len(a) m = len(b) ans = [0] * (n + m - 1) if n < m: for j in range(m): for i in range(n): ans[i + j] = (ans[i + j] + a[i] * b[j]) % _fft_mod else: for i in range(n): for j in range(m): ans[i + j] = (ans[i + j] + a[i] * b[j]) % _fft_mod return ans def _convolution_fft(a, b): a = a.copy() b = b.copy() n = len(a) m = len(b) z = 1 << (n + m - 2).bit_length() a += [0] * (z - n) _butterfly(a) b += [0] * (z - m) _butterfly(b) for i in range(z): a[i] = a[i] * b[i] % _fft_mod _butterfly_inv(a) a = a[:n + m - 1] iz = pow(z, _fft_mod - 2, _fft_mod) for i in range(n + m - 1): a[i] = a[i] * iz % _fft_mod return a def _convolution_square(a): a = a.copy() n = len(a) z = 1 << (2 * n - 2).bit_length() a += [0] * (z - n) _butterfly(a) for i in range(z): a[i] = a[i] * a[i] % _fft_mod _butterfly_inv(a) a = a[:2 * n - 1] iz = pow(z, _fft_mod - 2, _fft_mod) for i in range(2 * n - 1): a[i] = a[i] * iz % _fft_mod return a def convolution(a, b): """It calculates (+, x) convolution in mod 998244353. Given two arrays a[0], a[1], ..., a[n - 1] and b[0], b[1], ..., b[m - 1], it calculates the array c of length n + m - 1, defined by > c[i] = sum(a[j] * b[i - j] for j in range(i + 1)) % 998244353. It returns an empty list if at least one of a and b are empty. Constraints ----------- > len(a) + len(b) <= 8388609 Complexity ---------- > O(n log n), where n = len(a) + len(b). """ n = len(a) m = len(b) if n == 0 or m == 0: return [] if min(n, m) <= 15: return _convolution_naive(a, b) if a is b: return _convolution_square(a) return _convolution_fft(a, b) import sys,random,bisect from collections import deque,defaultdict from heapq import heapify,heappop,heappush from itertools import permutations from math import gcd,log input = lambda :sys.stdin.readline().rstrip() mi = lambda :map(int,input().split()) li = lambda :list(mi()) def Z_algorithm(s): N = len(s) Z_alg = [0]*N Z_alg[0] = N i = 1 j = 0 while i < N: while i+j < N and s[j] == s[i+j]: j += 1 Z_alg[i] = j if j == 0: i += 1 continue k = 1 while i+k < N and k + Z_alg[k]<j: Z_alg[i+k] = Z_alg[k] k += 1 i += k j -= k return Z_alg import copy import functools import typing def _sa_naive(s: typing.List[int]) -> typing.List[int]: sa = list(range(len(s))) return sorted(sa, key=lambda i: s[i:]) def _sa_doubling(s: typing.List[int]) -> typing.List[int]: n = len(s) sa = list(range(n)) rnk = copy.deepcopy(s) tmp = [0] * n k = 1 while k < n: def cmp(x: int, y: int) -> bool: if rnk[x] != rnk[y]: return rnk[x] - rnk[y] rx = rnk[x + k] if x + k < n else -1 ry = rnk[y + k] if y + k < n else -1 return rx - ry sa.sort(key=functools.cmp_to_key(cmp)) tmp[sa[0]] = 0 for i in range(1, n): tmp[sa[i]] = tmp[sa[i - 1]] + (1 if cmp(sa[i - 1], sa[i]) else 0) tmp, rnk = rnk, tmp k *= 2 return sa def _sa_is(s: typing.List[int], upper: int) -> typing.List[int]: ''' SA-IS, linear-time suffix array construction Reference: G. Nong, S. Zhang, and W. H. Chan, Two Efficient Algorithms for Linear Time Suffix Array Construction ''' threshold_naive = 10 threshold_doubling = 40 n = len(s) if n == 0: return [] if n == 1: return [0] if n == 2: if s[0] < s[1]: return [0, 1] else: return [1, 0] if n < threshold_naive: return _sa_naive(s) if n < threshold_doubling: return _sa_doubling(s) sa = [0] * n ls = [False] * n for i in range(n - 2, -1, -1): if s[i] == s[i + 1]: ls[i] = ls[i + 1] else: ls[i] = s[i] < s[i + 1] sum_l = [0] * (upper + 1) sum_s = [0] * (upper + 1) for i in range(n): if not ls[i]: sum_s[s[i]] += 1 else: sum_l[s[i] + 1] += 1 for i in range(upper + 1): sum_s[i] += sum_l[i] if i < upper: sum_l[i + 1] += sum_s[i] def induce(lms: typing.List[int]) -> None: nonlocal sa sa = [-1] * n buf = copy.deepcopy(sum_s) for d in lms: if d == n: continue sa[buf[s[d]]] = d buf[s[d]] += 1 buf = copy.deepcopy(sum_l) sa[buf[s[n - 1]]] = n - 1 buf[s[n - 1]] += 1 for i in range(n): v = sa[i] if v >= 1 and not ls[v - 1]: sa[buf[s[v - 1]]] = v - 1 buf[s[v - 1]] += 1 buf = copy.deepcopy(sum_l) for i in range(n - 1, -1, -1): v = sa[i] if v >= 1 and ls[v - 1]: buf[s[v - 1] + 1] -= 1 sa[buf[s[v - 1] + 1]] = v - 1 lms_map = [-1] * (n + 1) m = 0 for i in range(1, n): if not ls[i - 1] and ls[i]: lms_map[i] = m m += 1 lms = [] for i in range(1, n): if not ls[i - 1] and ls[i]: lms.append(i) induce(lms) if m: sorted_lms = [] for v in sa: if lms_map[v] != -1: sorted_lms.append(v) rec_s = [0] * m rec_upper = 0 rec_s[lms_map[sorted_lms[0]]] = 0 for i in range(1, m): left = sorted_lms[i - 1] right = sorted_lms[i] if lms_map[left] + 1 < m: end_l = lms[lms_map[left] + 1] else: end_l = n if lms_map[right] + 1 < m: end_r = lms[lms_map[right] + 1] else: end_r = n same = True if end_l - left != end_r - right: same = False else: while left < end_l: if s[left] != s[right]: break left += 1 right += 1 if left == n or s[left] != s[right]: same = False if not same: rec_upper += 1 rec_s[lms_map[sorted_lms[i]]] = rec_upper rec_sa = _sa_is(rec_s, rec_upper) for i in range(m): sorted_lms[i] = lms[rec_sa[i]] induce(sorted_lms) return sa def suffix_array(s: typing.Union[str, typing.List[int]], upper: typing.Optional[int] = None) -> typing.List[int]: if isinstance(s, str): return _sa_is([ord(c) for c in s], 255) elif upper is None: n = len(s) idx = list(range(n)) idx.sort(key=functools.cmp_to_key(lambda l, r: s[l] - s[r])) s2 = [0] * n now = 0 for i in range(n): if i and s[idx[i - 1]] != s[idx[i]]: now += 1 s2[idx[i]] = now return _sa_is(s2, now) else: assert 0 <= upper for d in s: assert 0 <= d <= upper return _sa_is(s, upper) def lcp_array(s: typing.Union[str, typing.List[int]], sa: typing.List[int]) -> typing.List[int]: ''' Reference: T. Kasai, G. Lee, H. Arimura, S. Arikawa, and K. Park, Linear-Time Longest-Common-Prefix Computation in Suffix Arrays and Its Applications ''' if isinstance(s, str): s = [ord(c) for c in s] n = len(s) assert n >= 1 rnk = [0] * n for i in range(n): rnk[sa[i]] = i lcp = [0] * (n - 1) h = 0 for i in range(n): if h > 0: h -= 1 if rnk[i] == 0: continue j = sa[rnk[i] - 1] while j + h < n and i + h < n: if s[j + h] != s[i + h]: break h += 1 lcp[rnk[i] - 1] = h return lcp def solve(N,M,S,T): Sa = S.replace("?","a") SaT = T + "#" + Sa check = Z_algorithm(SaT) for i in range(N): if check[i+M+1] == M: return Sa SaT_suffix = Sa + "#" + T X = suffix_array(SaT_suffix) pos = [-1] * (N+M+1) for i in range(N+M+1): pos[X[i]] = i """ Sの?を置き換える際は ・かならず?->a以外にするとこがある(->?を置き換える部分がある) S[i:i+M] と S[j:j+M] (i < j) の置き換えを比較するとき、 i+M < j のとき、jが小さい T[:j-i]とSa[i:j] の比較 T[j-i:M] と T[:i+M-j] の比較 Sa[i+M:j+M] と T[i+M-j:M] の比較 これで決着がつかない場合、iが小さい """ wild_cnt = [0] + [S[i]=="?" for i in range(N)] for i in range(N): wild_cnt[i+1] += wild_cnt[i] T_Z = Z_algorithm(T) def compare(i,j): if i+M <= j: return j #print(i,j,check,SaT,check[i+M+1],Sa[check[i+M+1]]) if check[i+M+1] < j-i: if T[check[i+M+1]] < Sa[i+check[i+M+1]]: return i else: return j if T_Z[j-i] < M+i-j: if T[j-i+T_Z[j-i]] > T[T_Z[j-i]]: return j else: return i if pos[i+M] < pos[N+1+i+M-j]: return i else: return j hash = [k+1 for k in range(26)] f = [0] * N for i in range(N): if S[i]!="?": f[i] = hash[ord(S[i])-ord("a")] g = [0] * M for i in range(M): if T[i]!="?": g[i] = hash[ord(T[i])-ord("a")] p = convolution([f[i]**3 % mod for i in range(N)],g[::-1]) q = convolution([f[i]**2 % mod for i in range(N)],[g[i]**2 % mod for i in range(M)][::-1]) r = convolution([f[i] % mod for i in range(N)],[g[i]**3 % mod for i in range(M)][::-1]) cand = [] for i in range(N-M+1): if (p[i+M-1]-2*q[i+M-1]+r[i+M-1]) % mod == 0: cand.append(i) #print(cand) if not cand: return -1 k = cand[0] for i in cand[1:]: k = compare(k,i) res = "".join([S[:k].replace("?","a") , T , S[k+M:].replace("?","a")]) return res def brute(N,M,S,T): res = "z" * (N+1) for i in range(N-M+1): flag = True for j in range(M): if S[i+j]!="?" and S[i+j]!=T[j]: flag = False if flag: tmp = S[:i].replace("?","a") + T + S[i+M:].replace("?","a") res = min(res,tmp) if len(res) == N + 1: return -1 else: return res while False: N = random.randint(2,20) M = random.randint(1,N) S = "".join([random.choice("abc?") for i in range(N)]) T = "".join([random.choice("abc") for i in range(M)]) if solve(N,M,S,T)!=brute(N,M,S,T): print(N,M) print(S) print(T) print(solve(N,M,S,T),brute(N,M,S,T)) break else: print("AC") for _ in range(int(input())): N,M = mi() S = input() T = input() print(solve(N,M,S,T))