|  | 
| 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