1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
MOD = 10**9 + 7
def string_transformation(s: str, t: str, k: int) -> int:
n = len(s)
# Find all rotations of s that match t
good = 0
for i in range(n):
if s[i:] + s[:i] == t:
good += 1
bad = n - good
# Markov chain: [ways to be at t, ways to not be at t]
# Transition matrix:
# [good-1, good]
# [bad, bad-1]
# But since all rotations are reachable, we can use recurrence:
# Let dp[0] = 1 if s == t else 0
# dp[i] = good * dp[i-1] + bad * (total - dp[i-1])
# This is equivalent to: dp[i] = (good-1)*dp[i-1] + bad*(n-1)^(i-1)
# But we can use matrix exponentiation for the two states
def mat_mult(a, b):
return [
[(a[0][0]*b[0][0] + a[0][1]*b[1][0]) % MOD, (a[0][0]*b[0][1] + a[0][1]*b[1][1]) % MOD],
[(a[1][0]*b[0][0] + a[1][1]*b[1][0]) % MOD, (a[1][0]*b[0][1] + a[1][1]*b[1][1]) % MOD],
]
def mat_pow(mat, power):
res = [[1,0],[0,1]]
while power:
if power % 2:
res = mat_mult(res, mat)
mat = mat_mult(mat, mat)
power //= 2
return res
# State: [at t, not at t]
# Transition: [[good, bad], [good, bad]]
trans = [[good-1, good], [bad, bad-1]]
# Initial state: at t if s==t else not at t
init = [1 if s == t else 0, 0 if s == t else 1]
mat = mat_pow([[good-1, good], [bad, bad-1]], k)
ans = (mat[0][0]*init[0] + mat[0][1]*init[1]) % MOD
return ans
|