|
1 | 1 | package g3301_3400.s3337_total_characters_in_string_after_transformations_ii |
2 | 2 |
|
3 | 3 | // #Hard #String #Hash_Table #Dynamic_Programming #Math #Counting |
4 | | -// #2024_10_29_Time_320_ms_(100.00%)_Space_44_MB_(33.33%) |
| 4 | +// #2025_05_14_Time_302_ms_(100.00%)_Space_54.72_MB_(100.00%) |
5 | 5 |
|
6 | 6 | class Solution { |
7 | 7 | fun lengthAfterTransformations(s: String, t: Int, nums: List<Int>): Int { |
8 | | - val m = Array<IntArray>(26) { IntArray(26) } |
9 | | - for (i in 0..25) { |
10 | | - for (j in 1..nums[i]) { |
11 | | - m[(i + j) % 26][i] = m[(i + j) % 26][i] + 1 |
12 | | - } |
13 | | - } |
14 | | - var v = IntArray(26) |
| 8 | + val localT = buildTransformationMatrix(nums) |
| 9 | + val tPower = matrixPower(localT, t) |
| 10 | + val freq = IntArray(26) |
15 | 11 | for (c in s.toCharArray()) { |
16 | | - v[c.code - 'a'.code]++ |
| 12 | + freq[c.code - 'a'.code]++ |
17 | 13 | } |
18 | | - v = pow(m, v, t.toLong()) |
19 | | - var ans: Long = 0 |
20 | | - for (x in v) { |
21 | | - ans += x.toLong() |
| 14 | + var result: Long = 0 |
| 15 | + for (i in 0..25) { |
| 16 | + var sum: Long = 0 |
| 17 | + for (j in 0..25) { |
| 18 | + sum = (sum + freq[j].toLong() * tPower[j][i]) % MOD |
| 19 | + } |
| 20 | + result = (result + sum) % MOD |
22 | 21 | } |
23 | | - return (ans % MOD).toInt() |
| 22 | + return result.toInt() |
24 | 23 | } |
25 | 24 |
|
26 | | - // A^e*v |
27 | | - private fun pow(a: Array<IntArray>, v: IntArray, e: Long): IntArray { |
28 | | - var v = v |
29 | | - var e = e |
30 | | - for (i in v.indices) { |
31 | | - if (v[i] >= MOD) { |
32 | | - v[i] %= MOD |
33 | | - } |
34 | | - } |
35 | | - var mul = a |
36 | | - while (e > 0) { |
37 | | - if ((e and 1L) == 1L) { |
38 | | - v = mul(mul, v) |
| 25 | + private fun buildTransformationMatrix(numsList: List<Int>): Array<IntArray> { |
| 26 | + val localT = Array(26) { IntArray(26) } |
| 27 | + for (i in 0..25) { |
| 28 | + val steps: Int = numsList[i] |
| 29 | + for (j in 1..steps) { |
| 30 | + localT[i][(i + j) % 26] = localT[i][(i + j) % 26] + 1 |
39 | 31 | } |
40 | | - mul = p2(mul) |
41 | | - e = e ushr 1 |
42 | 32 | } |
43 | | - return v |
| 33 | + return localT |
44 | 34 | } |
45 | 35 |
|
46 | | - // int matrix*int vector |
47 | | - private fun mul(a: Array<IntArray>, v: IntArray): IntArray { |
48 | | - val m = a.size |
49 | | - val n = v.size |
50 | | - val w = IntArray(m) |
51 | | - for (i in 0 until m) { |
52 | | - var sum: Long = 0 |
53 | | - for (k in 0 until n) { |
54 | | - sum += a[i][k].toLong() * v[k] |
55 | | - if (sum >= BIG) { |
56 | | - sum -= BIG |
57 | | - } |
| 36 | + private fun matrixPower(matrix: Array<IntArray>, power: Int): Array<IntArray> { |
| 37 | + var matrix = matrix |
| 38 | + var power = power |
| 39 | + val size = matrix.size |
| 40 | + var result = Array(size) { IntArray(size) } |
| 41 | + for (i in 0..<size) { |
| 42 | + result[i][i] = 1 |
| 43 | + } |
| 44 | + while (power > 0) { |
| 45 | + if ((power and 1) == 1) { |
| 46 | + result = multiplyMatrices(result, matrix) |
58 | 47 | } |
59 | | - w[i] = (sum % MOD).toInt() |
| 48 | + matrix = multiplyMatrices(matrix, matrix) |
| 49 | + power = power shr 1 |
60 | 50 | } |
61 | | - return w |
| 51 | + return result |
62 | 52 | } |
63 | 53 |
|
64 | | - // int matrix^2 (be careful about negative value) |
65 | | - private fun p2(a: Array<IntArray>): Array<IntArray> { |
66 | | - val n = a.size |
67 | | - val c = Array<IntArray>(n) { IntArray(n) } |
68 | | - for (i in 0 until n) { |
69 | | - val sum = LongArray(n) |
70 | | - for (k in 0 until n) { |
71 | | - for (j in 0 until n) { |
72 | | - sum[j] += a[i][k].toLong() * a[k][j] |
73 | | - if (sum[j] >= BIG) { |
74 | | - sum[j] -= BIG |
75 | | - } |
| 54 | + private fun multiplyMatrices(a: Array<IntArray>, b: Array<IntArray>): Array<IntArray> { |
| 55 | + val size = a.size |
| 56 | + val result = Array(size) { IntArray(size) } |
| 57 | + for (i in 0..<size) { |
| 58 | + for (k in 0..<size) { |
| 59 | + if (a[i][k] == 0) { |
| 60 | + continue |
| 61 | + } |
| 62 | + for (j in 0..<size) { |
| 63 | + result[i][j] = ((result[i][j] + a[i][k].toLong() * b[k][j]) % MOD).toInt() |
76 | 64 | } |
77 | | - } |
78 | | - for (j in 0 until n) { |
79 | | - c[i][j] = (sum[j] % MOD).toInt() |
80 | 65 | } |
81 | 66 | } |
82 | | - return c |
| 67 | + return result |
83 | 68 | } |
84 | 69 |
|
85 | 70 | companion object { |
86 | | - const val MOD: Int = 1000000007 |
87 | | - const val M2: Long = MOD.toLong() * MOD |
88 | | - const val BIG: Long = 8L * M2 |
| 71 | + private const val MOD = 1000000007 |
89 | 72 | } |
90 | 73 | } |
0 commit comments