Advertisement
vkazar

Untitled

Oct 27th, 2023
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 2.46 KB | None | 0 0
  1. package sprint4.tasks.I
  2.  
  3. import java.io.BufferedReader
  4. import java.io.InputStreamReader
  5. import java.util.*
  6. import kotlin.math.min
  7. import kotlin.math.pow
  8.  
  9. const val a = 1000000011
  10. const val M = Int.MAX_VALUE
  11.  
  12. fun main() {
  13.  
  14.     val bufferedReader = BufferedReader(InputStreamReader(System.`in`))
  15.     val firstArr = bufferedReader.readResults()
  16.     val secondArr = bufferedReader.readResults()
  17.     val h = getCommonSubArrayLen(firstArr, secondArr, min(firstArr.size, secondArr.size))
  18.     println(h)
  19. }
  20.  
  21. private fun getCommonSubArrayLen(
  22.     firstArr: List<Int>,
  23.     secondArr: List<Int>,
  24.     h: Int,
  25.     prevCandidate: Int = 0
  26. ): Int {
  27.     if (h == prevCandidate) return prevCandidate
  28.  
  29.     return when (checkSubArrayExists(firstArr, secondArr, h)) {
  30.         true -> {
  31.             val minSize = min(firstArr.size, secondArr.size)
  32.             val newH = (h + minSize) / 2
  33.             getCommonSubArrayLen(firstArr, secondArr, newH, h)
  34.         }
  35.         else -> {
  36.             val newH = (h + prevCandidate) / 2
  37.             getCommonSubArrayLen(firstArr, secondArr, newH, prevCandidate)
  38.         }
  39.     }
  40. }
  41.  
  42. private fun checkSubArrayExists(firstArr: List<Int>, secondArr: List<Int>, h: Int): Boolean {
  43.     val set = firstArr.subListHashCodes(h).toSet()
  44.     return secondArr.subListHashCodes(h).any { set.contains(it) }
  45. }
  46.  
  47. fun Int.pow(pow: Int) = toDouble().pow(pow).toInt()
  48.  
  49. private fun <T> List<T>.subListHashCodes(len: Int): Sequence<Int> {
  50.     var currHash: Long? = 0
  51.     var left = 0
  52.     val aPow = if (len != size) a.toBigInteger().modPow((len - 1).toBigInteger(), M.toBigInteger()).toLong() else 0L
  53.     return generateSequence {
  54.         currHash = when (left) {
  55.             0 -> subList(0, len).customHash()
  56.             in (1..(size - len)) -> {
  57.                 val toDelElement = this[left - 1]
  58.                 val toAddElement = this[left + len - 1]
  59.                 (((currHash!! - toDelElement.hashCode() * aPow % M + M) % M) * a % M + toAddElement.hashCode()) % M
  60.             }
  61.             else -> null
  62.         }
  63.  
  64.         left++
  65.         currHash?.toInt()
  66.     }
  67. }
  68.  
  69. private fun <T> List<T>.customHash(): Long {
  70.     var hashCode = 0L
  71.     for (e in this) {
  72.         hashCode = (a * hashCode % M + e.hashCode() % M) % M
  73.     }
  74.     return hashCode
  75. }
  76.  
  77. private fun BufferedReader.readResults(): List<Int> {
  78.     val size = readLine().toInt()
  79.     val tokenizer = StringTokenizer(readLine())
  80.     return List(size) { tokenizer.nextToken().toInt() }
  81. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement