Advertisement
vkazar

Untitled

Oct 6th, 2023
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 2.20 KB | None | 0 0
  1. package sprint4.tasks.C
  2.  
  3. import java.io.BufferedReader
  4. import java.io.InputStreamReader
  5. import java.util.*
  6. import kotlin.math.pow
  7.  
  8. fun String.polynomialHashToArray(a: Int, m: Int): LongArray {
  9.     val result = LongArray(length)
  10.     var res = 0L
  11.     for (i in 0..lastIndex) {
  12.         res = (res * a % m + this[i].code) % m
  13.         result[i] = res
  14.     }
  15.  
  16.     return result
  17. }
  18.  
  19. fun LongArray.calcSubStringHash(left: Int, right: Int, a: Int, m: Int): Long {
  20.     val rightHash = this[right]
  21.     val leftMinusOneHash = if (left == 0) 0 else this[left - 1]
  22.     val aPow = a.pow5(right - left + 1, m) % m
  23.     return ((rightHash - (leftMinusOneHash * aPow) % m + m) % m)
  24. }
  25.  
  26. //ИЗначально использовался этот метод, но выходит за рамки дабла Оо
  27. fun Int.pow(pow: Int, m: Int) = (toDouble().pow(pow) % m).toLong()
  28.  
  29. //работает корректно, но долго
  30. fun Int.pow2(pow: Int, m: Int): Long {
  31.     var res = 1L
  32.     for (i in 1..pow) res = res * this % m
  33.     return res
  34. }
  35.  
  36. //тоже работает, но тоже долго
  37. fun Int.pow3(pow: Int, m: Int) = (toBigInteger().pow(pow).divideAndRemainder(m.toBigInteger())[1]).toLong()
  38.  
  39. //это тоже ожидаемо долго
  40. fun Int.pow4(pow: Int, m: Int): Long {
  41.     if (pow <= 120) return (toDouble().pow(pow) % m).toLong()
  42.     return (pow4(pow / 2, m) * pow4(pow - pow / 2, m)) % m
  43. }
  44.  
  45. //корректно и в пределах TL
  46. fun Int.pow5(pow: Int, m: Int) = (toBigInteger().modPow(pow.toBigInteger(), m.toBigInteger())).toLong()
  47.  
  48. fun StringTokenizer.nextInt() = nextToken().toInt()
  49.  
  50. fun main() {
  51.     val reader = BufferedReader(InputStreamReader(System.`in`))
  52.     val a = reader.readLine().toInt()
  53.     val m = reader.readLine().toInt()
  54.     val str = reader.readLine()
  55.     val prefixHashes = str.polynomialHashToArray(a, m)
  56.     val sb = StringBuilder()
  57.     repeat(reader.readLine().toInt()) {
  58.         val tokenizer = StringTokenizer(reader.readLine())
  59.         val left = tokenizer.nextInt() - 1
  60.         val right = tokenizer.nextInt() - 1
  61.  
  62.         val curResult = prefixHashes.calcSubStringHash(left, right, a, m)
  63.         sb.appendLine(curResult)
  64.     }
  65.     println(sb)
  66. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement