結果
| 問題 |
No.430 文字列検索
|
| コンテスト | |
| ユーザー |
Risu_Basquiat
|
| 提出日時 | 2020-06-20 00:25:53 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 210 ms / 2,000 ms |
| コード長 | 2,235 bytes |
| コンパイル時間 | 399 ms |
| コンパイル使用メモリ | 82,304 KB |
| 実行使用メモリ | 132,352 KB |
| 最終ジャッジ日時 | 2024-11-10 00:44:35 |
| 合計ジャッジ時間 | 3,098 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 14 |
ソースコード
import math
import sys
from collections import Counter#文字列を個数カウント辞書に、
def input():
x=sys.stdin.readline()
return x[:-1] if x[-1]=="\n" else x
def alp2num(c,cap=False): return ord(c)-97 if not cap else ord(c)-65
import random
class rh:#base,max_n,convertを指定すること
def __init__(self,base,max_n):#baseとmaxnを指定すること。baseは偶数(modが奇数)
self.mod=random.randrange(1<<54-1,1<<55-1,2)#奇数、衝突させられないよう乱数で生成
self.base=int(base*0.5+0.5)*2#偶数,英小文字なら26とか
self.max_n=max_n
self.pows1=[1]*(max_n+1)
cur1=cur2=1
for i in range(1,max_n+1):
cur1=cur1*base%self.mod
self.pows1[i]=cur1
def convert(self,c): return alp2num(c,True)
def get(self, s):#特定の文字のhash. O(|s|)
n=len(s)
mod=self.mod
si=[self.convert(ss) for ss in s]
h1=sum([si[i]*self.pows1[n-1-i]%mod for i in range(n)])%mod
return h1
def get_roll(self, s, k):#ローリングハッシュ,特定の文字の中から長さkのhashをすべて得る,O(|s|)
n=len(s)
si=[self.convert(ss) for ss in s]
mod=self.mod
h1=sum([si[i]*self.pows1[k-1-i]%mod for i in range(k)])%mod
hs=[0]*(n-k+1)
hs[0]=h1
mbase1=self.pows1[k]
base=self.base
for i in range(1,n-k+1):
front=si[i-1];back=si[i+k-1]
h1=(h1*base-front*mbase1+back)%mod
hs[i]=h1
return hs
def rc(s,k,rh):
hs=rh.get_roll(s,k)
cnt=set()
for i, h in enumerate(hs):
if h in cnt:
return s[i:i+k]
else:
cnt.add(h)
return 0
def main():
s=input()
M=int(input())
rhi=rh(26,len(s))
l=[]
for k in range(1,min(len(s)+1,11)):
l.append(Counter(rhi.get_roll(s,k)))
ans=0
for m in range(M):
c=input()
k=len(c)
if k>len(s):
continue
ch=rhi.get(c)
#print(len(l))
if ch in l[k-1]:
ans+=l[k-1][ch]
print(ans)
if __name__ == "__main__":
main()
#print(pows1)
Risu_Basquiat