Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package sprint4.tasks.I
- import java.io.BufferedReader
- import java.io.InputStreamReader
- import java.util.*
- import kotlin.math.min
- import kotlin.math.pow
- const val a = 1000000011
- const val M = Int.MAX_VALUE
- fun main() {
- val bufferedReader = BufferedReader(InputStreamReader(System.`in`))
- val firstArr = bufferedReader.readResults()
- val secondArr = bufferedReader.readResults()
- val h = getCommonSubArrayLen(firstArr, secondArr, min(firstArr.size, secondArr.size))
- println(h)
- }
- private fun getCommonSubArrayLen(
- firstArr: List<Int>,
- secondArr: List<Int>,
- h: Int,
- prevCandidate: Int = 0
- ): Int {
- if (h == prevCandidate) return prevCandidate
- return when (checkSubArrayExists(firstArr, secondArr, h)) {
- true -> {
- val minSize = min(firstArr.size, secondArr.size)
- val newH = (h + minSize) / 2
- getCommonSubArrayLen(firstArr, secondArr, newH, h)
- }
- else -> {
- val newH = (h + prevCandidate) / 2
- getCommonSubArrayLen(firstArr, secondArr, newH, prevCandidate)
- }
- }
- }
- private fun checkSubArrayExists(firstArr: List<Int>, secondArr: List<Int>, h: Int): Boolean {
- val set = firstArr.subListHashCodes(h).toSet()
- return secondArr.subListHashCodes(h).any { set.contains(it) }
- }
- fun Int.pow(pow: Int) = toDouble().pow(pow).toInt()
- private fun <T> List<T>.subListHashCodes(len: Int): Sequence<Int> {
- var currHash: Long? = 0
- var left = 0
- val aPow = if (len != size) a.toBigInteger().modPow((len - 1).toBigInteger(), M.toBigInteger()).toLong() else 0L
- return generateSequence {
- currHash = when (left) {
- 0 -> subList(0, len).customHash()
- in (1..(size - len)) -> {
- val toDelElement = this[left - 1]
- val toAddElement = this[left + len - 1]
- (((currHash!! - toDelElement.hashCode() * aPow % M + M) % M) * a % M + toAddElement.hashCode()) % M
- }
- else -> null
- }
- left++
- currHash?.toInt()
- }
- }
- private fun <T> List<T>.customHash(): Long {
- var hashCode = 0L
- for (e in this) {
- hashCode = (a * hashCode % M + e.hashCode() % M) % M
- }
- return hashCode
- }
- private fun BufferedReader.readResults(): List<Int> {
- val size = readLine().toInt()
- val tokenizer = StringTokenizer(readLine())
- return List(size) { tokenizer.nextToken().toInt() }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement