https://coderun.yandex.ru/problem/advertising Средняя

Решение

import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.InputStreamReader
import java.io.OutputStreamWriter
import java.util.TreeSet
import java.util.BitSet
import java.util.HashMap
import kotlin.math.max

fun main(args: Array<String>) {
    val reader = BufferedReader(InputStreamReader(System.`in`))
    val writer = BufferedWriter(OutputStreamWriter(System.out))

    val n = reader.readLine().toInt()
    val potentialCustomers = ArrayList<Pair<Pair<Long, Long>, Int>>(n)
    var potentialCustomerCount = 0
    for (i in 0 until n) {
        val parts = reader.readLine().split(" ")
        val arrival = parts[0].toLong()
        val departure = parts[1].toLong()
        if (departure - arrival >= 5) {
             potentialCustomers.add(Pair(Pair(arrival, departure), i))
             potentialCustomerCount++
        }
    }

    if (potentialCustomerCount == 0) {
        writer.write("0 1 6\\n")
        writer.flush(); reader.close(); writer.close()
        return
    }

    val candidateTimesSet = TreeSet<Long>()
    for ((times, _) in potentialCustomers) {
        candidateTimesSet.add(times.first)
        candidateTimesSet.add(times.second - 5)
    }

    val sortedTimes = candidateTimesSet.toTypedArray()
    val C = sortedTimes.size

    if (C == 0) {
        writer.write("0 1 6\\n")
         writer.flush(); reader.close(); writer.close()
        return
    }

    val timeToIndex = HashMap<Long, Int>(C)
    sortedTimes.forEachIndexed { index, time -> timeToIndex[time] = index }

    val audienceArray = Array(C) { BitSet(potentialCustomerCount) }
    for (i in 0 until C) {
        val t = sortedTimes[i]
        for (idx in 0 until potentialCustomerCount) {
             val arrival = potentialCustomers[idx].first.first
             val departure = potentialCustomers[idx].first.second
             if (arrival <= t && departure >= t + 5) {
                 audienceArray[i].set(idx)
             }
        }
    }

    val audienceSizeArray = IntArray(C) { audienceArray[it].cardinality() }
    var maxListeners = 0
    var bestT1Idx = 0
    var bestT2Idx = -1

    for (i in 0 until C) {
        if (audienceSizeArray[i] > maxListeners) {
            maxListeners = audienceSizeArray[i]
            bestT1Idx = i
            bestT2Idx = -1
        }
    }

    val tempIntersection = BitSet(potentialCustomerCount)

    for (i in 0 until C) {
        val t1 = sortedTimes[i]
        val audience1 = audienceArray[i]
        val size1 = audienceSizeArray[i]
        val minT2Time = t1 + 5

        for (j in i until C) {
            val t2 = sortedTimes[j]
            if (t2 >= minT2Time) {
                val audience2 = audienceArray[j]
                val size2 = audienceSizeArray[j]

                tempIntersection.clear()
                tempIntersection.or(audience1)
                tempIntersection.and(audience2)
                val intersectionSize = tempIntersection.cardinality()

                val currentListeners = size1 + size2 - intersectionSize

                if (currentListeners > maxListeners) {
                    maxListeners = currentListeners
                    bestT1Idx = i
                    bestT2Idx = j
                }
            }
        }
    }

    val finalBestT1 = sortedTimes[bestT1Idx]
    val finalBestT2 = if (bestT2Idx == -1) {
        finalBestT1 + 5
    } else {
        sortedTimes[bestT2Idx]
    }

    writer.write("$maxListeners $finalBestT1 $finalBestT2\\n")
    reader.close()
    writer.flush()
    writer.close()
}