結果
| 問題 | No.1269 I hate Fibonacci Number |
| コンテスト | |
| ユーザー |
tpyneriver
|
| 提出日時 | 2021-01-11 13:21:48 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 4,121 bytes |
| コンパイル時間 | 465 ms |
| コンパイル使用メモリ | 82,304 KB |
| 実行使用メモリ | 168,960 KB |
| 最終ジャッジ日時 | 2024-11-21 09:02:00 |
| 合計ジャッジ時間 | 24,443 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 34 TLE * 2 |
ソースコード
import sys
readline = sys.stdin.readline
from collections import deque
class AhoCorasick:
def __init__(self, patterns):
self.patterns = patterns
self.children = [dict()]
self.N = 1
self.match = [False]
self.order = [0]
"""
例えばで、 self.match に patterns のうちどれかが部分文字列になっているかどうかを格納
禁止文字列とかの場合 self.match が True だと使えない
"""
for i in range(len(patterns)):
self._add(i, patterns[i])
self.failure = [0]*self.N
self._createfailure()
def _add(self, i, p):
vn = 0
for pi in p:
if pi in self.children[vn]:
vn = self.children[vn][pi]
else:
self.children[vn][pi] = self.N
self.children.append(dict())
self.match.append(False)
vn = self.N
self.N += 1
self.match[vn] = True
def _createfailure(self):
Q = deque(self.children[0].values())
while Q:
vn = Q.pop()
self.order.append(vn)
fvn = self.failure[vn]
self.match[vn] |= self.match[fvn]
for fpi, vf in self.children[vn].items():
self.failure[vf] = self.nxt(fvn, fpi)
self.match[vf] |= self.match[vn]
Q.appendleft(vf)
def nxt(self, vn, s):
#vnにsを付け足した時の遷移先
while True:
if s in self.children[vn]:
return self.children[vn][s]
if not vn:
return vn
vn = self.failure[vn]
def idx(self, p):
#文字列pのindexを返す
vn = 0
for pi in p:
if pi in self.children[vn]:
vn = self.children[vn][pi]
else:
return -1
return vn
def getnxttable(self, sigma):
#[0, sigma) に対して各ノードからの遷移先を求める
#res[s*self.N + vn] = nxt(vn, s)
res = [0]*(self.N*sigma)
for l in self.order:
for s in range(sigma):
if s in self.children[l]:
res[s*self.N + l] = self.children[l][s]
else:
res[s*self.N + l] = res[s*self.N + self.failure[l]]
return res
def __repr__(self):
SS = [None]*self.N
SS[0] = ''
Q = deque([0])
while Q:
vn = Q.pop()
for c, vf in self.children[vn].items():
SS[vf] = f'{SS[vn]} {c}'
Q.appendleft(vf)
return '\n'.join(f'{i}:{SS[i]} {self.match[i]}' for i in range(self.N))
N, L, R = map(int, readline().split())
MOD = 10**9+7
Fib = []
a, b = 1, 1
while b <= R:
Fib.append(b)
a, b = b, a+b
L -= 1
a, b = 1, 1
while b <= L:
Fib.remove(b)
a, b = b, a+b
Fib = [tuple(map(int, str(s))) for s in Fib]
ahc = AhoCorasick(Fib)
M = ahc.N
table = ahc.getnxttable(10)
J = [i for i in range(M) if not ahc.match[i]]
Lj = len(J)
AA = [[0]*Lj for _ in range(Lj)]
Ji = dict()
for jidx in range(Lj):
Ji[J[jidx]] = jidx
for j in J:
for s in range(10):
vf = table[s*M + j]
if not ahc.match[vf]:
AA[Ji[vf]][Ji[j]] += 1
def mat_dot(A, B):
assert len(A[0]) == len(B), 'invalid_size'
L = len(A)
M = len(A[0])
N = len(B[0])
res = [[0]*N for _ in range(L)]
for i in range(L):
for j in range(N):
a = 0
for k in range(M):
a = (a+A[i][k]*B[k][j]) % MOD
res[i][j] = a
return res
def mat_pow(A, x):
N = len(A)
res = [[0]*N for _ in range(N)]
for i in range(N):
res[i][i] = 1
for i in range(x.bit_length()):
if 2**i & x:
res = mat_dot(res, A)
A = mat_dot(A, A)
return res
dp = [[0] for _ in range(Lj)]
dp[0] = [1]
dp = mat_dot(mat_pow(AA, N), dp)
ans = MOD-1
for d in dp:
ans = (ans + d[0])%MOD
print(ans)
tpyneriver