|
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