結果
問題 | No.2626 Similar But Different Name |
ユーザー |
![]() |
提出日時 | 2024-02-09 23:27:45 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 2,747 ms / 3,000 ms |
コード長 | 11,106 bytes |
コンパイル時間 | 220 ms |
コンパイル使用メモリ | 82,244 KB |
実行使用メモリ | 266,320 KB |
最終ジャッジ日時 | 2024-09-28 16:35:16 |
合計ジャッジ時間 | 46,758 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 35 |
ソースコード
class FFT():def primitive_root_constexpr(self,m):if m==2:return 1if m==167772161:return 3if m==469762049:return 3if m==754974721:return 11if m==998244353:return 3divs=[0]*20divs[0]=2cnt=1x=(m-1)//2while(x%2==0):x//=2i=3while(i*i<=x):if (x%i==0):divs[cnt]=icnt+=1while(x%i==0):x//=ii+=2if x>1:divs[cnt]=xcnt+=1g=2while(1):ok=Truefor i in range(cnt):if pow(g,(m-1)//divs[i],m)==1:ok=Falsebreakif ok:return gg+=1def bsf(self,x):res=0while(x%2==0):res+=1x//=2return resrank2=0root=[]iroot=[]rate2=[]irate2=[]rate3=[]irate3=[]def __init__(self,MOD):self.mod=MODself.g=self.primitive_root_constexpr(self.mod)self.rank2=self.bsf(self.mod-1)self.root=[0 for i in range(self.rank2+1)]self.iroot=[0 for i in range(self.rank2+1)]self.rate2=[0 for i in range(self.rank2)]self.irate2=[0 for i in range(self.rank2)]self.rate3=[0 for i in range(self.rank2-1)]self.irate3=[0 for i in range(self.rank2-1)]self.root[self.rank2]=pow(self.g,(self.mod-1)>>self.rank2,self.mod)self.iroot[self.rank2]=pow(self.root[self.rank2],self.mod-2,self.mod)for i in range(self.rank2-1,-1,-1):self.root[i]=(self.root[i+1]**2)%self.modself.iroot[i]=(self.iroot[i+1]**2)%self.modprod=1;iprod=1for i in range(self.rank2-1):self.rate2[i]=(self.root[i+2]*prod)%self.modself.irate2[i]=(self.iroot[i+2]*iprod)%self.modprod=(prod*self.iroot[i+2])%self.modiprod=(iprod*self.root[i+2])%self.modprod=1;iprod=1for i in range(self.rank2-2):self.rate3[i]=(self.root[i+3]*prod)%self.modself.irate3[i]=(self.iroot[i+3]*iprod)%self.modprod=(prod*self.iroot[i+3])%self.modiprod=(iprod*self.root[i+3])%self.moddef butterfly(self,a):n=len(a)h=(n-1).bit_length()LEN=0while(LEN<h):if (h-LEN==1):p=1<<(h-LEN-1)rot=1for s in range(1<<LEN):offset=s<<(h-LEN)for i in range(p):l=a[i+offset]r=a[i+offset+p]*rota[i+offset]=(l+r)%self.moda[i+offset+p]=(l-r)%self.modrot*=self.rate2[(~s & -~s).bit_length()-1]rot%=self.modLEN+=1else:p=1<<(h-LEN-2)rot=1imag=self.root[2]for s in range(1<<LEN):rot2=(rot*rot)%self.modrot3=(rot2*rot)%self.modoffset=s<<(h-LEN)for i in range(p):a0=a[i+offset]a1=a[i+offset+p]*rota2=a[i+offset+2*p]*rot2a3=a[i+offset+3*p]*rot3a1na3imag=(a1-a3)%self.mod*imaga[i+offset]=(a0+a2+a1+a3)%self.moda[i+offset+p]=(a0+a2-a1-a3)%self.moda[i+offset+2*p]=(a0-a2+a1na3imag)%self.moda[i+offset+3*p]=(a0-a2-a1na3imag)%self.modrot*=self.rate3[(~s & -~s).bit_length()-1]rot%=self.modLEN+=2def butterfly_inv(self,a):n=len(a)h=(n-1).bit_length()LEN=hwhile(LEN):if (LEN==1):p=1<<(h-LEN)irot=1for 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)%self.moda[i+offset+p]=(l-r)*irot%self.modirot*=self.irate2[(~s & -~s).bit_length()-1]irot%=self.modLEN-=1else:p=1<<(h-LEN)irot=1iimag=self.iroot[2]for s in range(1<<(LEN-2)):irot2=(irot*irot)%self.modirot3=(irot*irot2)%self.modoffset=s<<(h-LEN+2)for i in range(p):a0=a[i+offset]a1=a[i+offset+p]a2=a[i+offset+2*p]a3=a[i+offset+3*p]a2na3iimag=(a2-a3)*iimag%self.moda[i+offset]=(a0+a1+a2+a3)%self.moda[i+offset+p]=(a0-a1+a2na3iimag)*irot%self.moda[i+offset+2*p]=(a0+a1-a2-a3)*irot2%self.moda[i+offset+3*p]=(a0-a1-a2na3iimag)*irot3%self.modirot*=self.irate3[(~s & -~s).bit_length()-1]irot%=self.modLEN-=2def convolution(self,a,b):n=len(a);m=len(b)if not(a) or not(b):return []if min(n,m)<=40:res=[0]*(n+m-1)for i in range(n):for j in range(m):res[i+j]+=a[i]*b[j]res[i+j]%=self.modreturn resz=1<<((n+m-2).bit_length())a=a+[0]*(z-n)b=b+[0]*(z-m)self.butterfly(a)self.butterfly(b)c=[(a[i]*b[i])%self.mod for i in range(z)]self.butterfly_inv(c)iz=pow(z,self.mod-2,self.mod)for i in range(n+m-1):c[i]=(c[i]*iz)%self.modreturn c[:n+m-1]class string:def sa_is(s,upper):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]sa=[0]*nls=[0]*nfor i in range(n-2,-1,-1):ls[i]=ls[i+1] if (s[i]==s[i+1]) else (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]]+=1else:sum_l[s[i]+1]+=1for i in range(upper+1):sum_s[i]+=sum_l[i]if i<upper:sum_l[i+1]+=sum_s[i]def induce(lms):for i in range(n):sa[i]=-1buf=sum_s[:]for d in lms:if d==n:continuesa[buf[s[d]]]=dbuf[s[d]]+=1buf=sum_l[:]sa[buf[s[n-1]]]=n-1buf[s[n-1]]+=1for i in range(n):v=sa[i]if v>=1 and not(ls[v-1]):sa[buf[s[v-1]]]=v-1buf[s[v-1]]+=1buf=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]-=1sa[buf[s[v-1]+1]]=v-1lms_map=[-1]*(n+1)m=0for i in range(1,n):if not(ls[i-1]) and ls[i]:lms_map[i]=mm+=1lms=[]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]*mrec_upper=0rec_s[lms_map[sorted_lms[0]]]=0for i in range(1,m):l=sorted_lms[i-1]r=sorted_lms[i]end_l=lms[lms_map[l]+1] if (lms_map[l]+1<m) else nend_r=lms[lms_map[r]+1] if (lms_map[r]+1<m) else nsame=Trueif end_l-l!=end_r-r:same=Falseelse:while(l<end_l):if s[l]!=s[r]:breakl+=1r+=1if (l==n) or (s[l]!=s[r]):same=Falseif not(same):rec_upper+=1rec_s[lms_map[sorted_lms[i]]]=rec_upperrec_sa=string.sa_is(rec_s,rec_upper)for i in range(m):sorted_lms[i]=lms[rec_sa[i]]induce(sorted_lms)return sadef suffix_array_upper(s,upper):assert 0<=upperfor d in s:assert 0<=d and d<=upperreturn string.sa_is(s,upper)def suffix_array(s):n=len(s)if type(s)==str:s2=[ord(i) for i in s]return string.sa_is(s2,255)else:idx=list(range(n))idx.sort(key=lambda x:s[x])s2=[0]*nnow=0for i in range(n):if (i& s[idx[i-1]]!=s[idx[i]]):now+=1s2[idx[i]]=nowreturn string.sa_is(s2,now)def lcp_array(s,sa):n=len(s)assert n>=1rnk=[0]*nfor i in range(n):rnk[sa[i]]=ilcp=[0]*(n-1)h=0for i in range(n):if h>0:h-=1if rnk[i]==0:continuej=sa[rnk[i]-1]while(j+h<n and i+h<n):if s[j+h]!=s[i+h]:breakh+=1lcp[rnk[i]-1]=hreturn lcpN,M,K = map(int,input().split())P,PP = [0 for i in range(N)],[0 for i in range(N)]Q,QQ = [0 for i in range(M)],[0 for i in range(M)]S = input()S = [S[i] for i in range(N)]for i in range(N):if ord(S[i]) < 97:P[i] = 1S[i] = ord(S[i]) - 65else:PP[i] = 1S[i] = ord(S[i]) - 97T = input()T = [T[i] for i in range(M)]for i in range(M):if ord(T[i]) < 97:QQ[i] = 1T[i] = ord(T[i]) - 65else:Q[i] = 1T[i] = ord(T[i]) - 97P = P[::-1]PP = PP[::-1]ans = [0 for i in range(N)]b = 100mod = 2**61 - 1for i in range(N):S[i] *= pow(b,i,mod)S[i] %= modfor i in range(M):T[i] *= pow(b,i,mod)T[i] %= modTT = sum(T) % modSS = 0for i in range(M):SS += S[i]SS %= modif SS == TT:ans[0] = 1for i in range(1,N-M+1):SS -= S[i-1]SS += S[i+M-1]SS %= modTT *= bTT %= modif SS == TT:ans[i] = 1CONV = FFT(998244353)F = CONV.convolution(P,Q)G = CONV.convolution(PP,QQ)for i in range(N):n = N - 1 - iif F[n] + G[n] > K:ans[i] = 0elif F[n] + G[n] == 0:ans[i] = 0print(sum(ans))