結果
問題 | No.674 n連勤 |
ユーザー |
|
提出日時 | 2021-02-23 14:29:24 |
言語 | Kotlin (2.1.0) |
結果 |
AC
|
実行時間 | 594 ms / 2,000 ms |
コード長 | 19,531 bytes |
コンパイル時間 | 29,329 ms |
コンパイル使用メモリ | 493,572 KB |
実行使用メモリ | 76,092 KB |
最終ジャッジ日時 | 2024-11-15 00:09:06 |
合計ジャッジ時間 | 36,816 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 17 |
コンパイルメッセージ
Main.kt:16:10: warning: variable 'd' is never used val (d, q) = readLong(2) ^ Main.kt:117:13: warning: parameter 'x' is never used fun mex(x: Long = 0): Long { ^ Main.kt:202:13: warning: 'appendln(Int): kotlin.text.StringBuilder /* = java.lang.StringBuilder */' is deprecated. Use appendLine instead. Note that the new method always appends the line feed character '\n' regardless of the system line separator. appendln(n) ^ Main.kt:235:48: warning: 'toByte(): Byte' is deprecated. Conversion of Char to Number is deprecated. Use Char.code property instead. private fun Byte.isNumeric() = this in '0'.toByte()..'9'.toByte() ^ Main.kt:235:62: warning: 'toByte(): Byte' is deprecated. Conversion of Char to Number is deprecated. Use Char.code property instead. private fun Byte.isNumeric() = this in '0'.toByte()..'9'.toByte() ^ Main.kt:236:68: warning: 'toByte(): Byte' is deprecated. Conversion of Char to Number is deprecated. Use Char.code property instead. private fun Byte.toNumVal() = if (this.isNumeric()) this - '0'.toByte() else error("$this is not numeric") ^ Main.kt:268:22: warning: 'toByte(): Byte' is deprecated. Conversion of Char to Number is deprecated. Use Char.code property instead. if (b == '-'.toByte()) { ^ Main.kt:294:22: warning: 'toByte(): Byte' is deprecated. Conversion of Char to Number is deprecated. Use Char.code property instead. if (b == '-'.toByte()) { ^ Main.kt:300:22: warning: 'toByte(): Byte' is deprecated. Conversion of Char to Number is deprecated. Use Char.code property instead. if (b == '.'.toByte()) { ^
ソースコード
import java.io.ByteArrayInputStreamimport java.io.ByteArrayOutputStreamimport java.io.PrintStreamimport java.util.*import kotlin.collections.ArrayDequeimport kotlin.math.absimport kotlin.math.maximport kotlin.math.minfun main() = if (localEnv && execChecker) checker() else p674()fun p674() = solve()@OptIn(ExperimentalStdlibApi::class)private fun solve() = Messiah_p674(MOD).exec {val (d, q) = readLong(2)val ranges = Array(q.toInt()) { readLong()..readLong() }val rangeSet = RangeSet()for (range in ranges) {rangeSet += rangeval answer = rangeSet.maxLengthprintln(answer)}}/*** todo とりあえず [a,b],[b,c] な区間はマージするように実装するけど切り替えできるようにしたい* todo range set 同士のマージもできるようにする?*/@ExperimentalStdlibApiprivate class RangeSet {val ranges: ArrayDeque<LongRange> = ArrayDeque<LongRange>().apply { add(-INF..-INF); add(INF..INF) }var maxLength = 0L/*** 点を挿入* @return 増やした点の数?*/fun add(x: Long): Long = add(x..x)/*** 範囲を挿入* @return 増やした点の数?*/fun add(range: LongRange): Long {checkRange(range)var (l, r) = rangevar i = ranges.lowerBound(range) - 1if (ranges[i].first <= l && l - 1 <= ranges[i].last) {l = min(l, ranges[i].first)r = max(r, ranges[i].last)ranges.removeAt(i)} else i++while (true) {if (ranges[i].first !in l..r + 1) breakr = max(r, ranges[i].last)ranges.removeAt(i)}maxLength = max(maxLength, r - l + 1)ranges.add(i, l..r)return 0 // todo}/*** 点を削除* @return 消した点の数?*/fun remove(x: Long): Long = remove(x..x)/*** 範囲を削除* @return 消した点の数?*/fun remove(range: LongRange): Long {checkRange(range)TODO()}/*** 点が含まれているかの判定*/operator fun contains(x: Long) = contains(x..x)/*** 指定の範囲が全部含まれているかの判定* todo 一部含まれているかとか、 intersect なやつもあってもいいかも?*/operator fun contains(range: LongRange): Boolean {// todo containBy を呼び出せばいいのでは?checkRange(range)TODO()}/*** 指定の点を含んでいる範囲を返す* 含まれていない場合は null を返す*/fun containBy(x: Long): LongRange? = containBy(x..x)/*** 指定の範囲を含んでいる範囲を返す* 含まれていない場合は null を返す*/fun containBy(range: LongRange): LongRange? {checkRange(range)TODO()}/*** Mex: 最小除外数(Minimum excludant) を返す*/fun mex(x: Long = 0): Long {TODO()}/*** 区間に含まれる点の数を返す* todo デカいとオーバーフローするけどどうしよう*/fun count(): Long {var sum = 0Lfor (range in ranges) sum += range.last - range.first + 1return sum}/*** 範囲の数*/val size: Int get() = ranges.size - 2operator fun plusAssign(x: Long): Unit = run { add(x) }operator fun plusAssign(range: LongRange): Unit = run { add(range) }operator fun minusAssign(x: Long): Unit = run { remove(x) }operator fun minusAssign(range: LongRange): Unit = run { remove(range) }override fun toString(): String = "RangeSet(ranges=${ranges.drop(1).dropLast(1)})"override fun equals(other: Any?): Boolean {if (this === other) return trueif (other !is RangeSet) return falseif (ranges != other.ranges) return falsereturn true}override fun hashCode(): Int = ranges.hashCode()companion object {private const val INF = Long.MAX_VALUE / 10 * 9private operator fun LongRange.contains(other: LongRange): Boolean = this.first in other && this.last in otherprivate operator fun LongRange.component1(): Long = this.firstprivate operator fun LongRange.component2(): Long = this.lastprivate fun checkRange(value: Long): Unit = check(value in -INF + 1 until INF)private fun checkRange(range: LongRange): Unit = check(range.first <= INF && range.last <= INF)private fun ArrayDeque<LongRange>.lowerBound(range: LongRange): Int {var ng = -1var ok = sizewhile (abs(ok - ng) > 1) {val mid = (ok + ng) / 2if (this[mid].first >= range.first) ok = mid else ng = mid}return ok}}}private const val MOD = 1_000_000_007// region kokokara template dayo (^o^)private const val execChecker = falseprivate val localEnv =runCatching { "ENABLE_DEBUG_MODE_FOR_COMPETITIVE_PROGRAMING" in System.getenv() }.getOrNull() ?: falseprivate fun checker() = Messiah_p674(MOD).exec {debugln("#######################################################")debugln("############### executing check mode. ###############")debugln("#######################################################")fun getOutPut(input: String, action: () -> Unit): String {System.setIn(ByteArrayInputStream(input.toByteArray()))val sysOut = ByteArrayOutputStream()System.setOut(PrintStream(sysOut))action()return sysOut.toString()}val wrongCases = mutableSetOf<List<String>>()while (wrongCases.size < 10) {/*examplesval randomString = (1..20).map { ('a'..'z').random() }.joinToString("")val randomNum = Random.nextInt(0,2000)*/val n = 0val input = buildString {appendln(n)}val solve = getOutPut(input, ::solve)val greedy = getOutPut(input, ::greedy)if (solve != greedy && wrongCases.add(listOf(solve, greedy))) {debugln("#################### wrong case: ${wrongCases.size} ####################")debugln("input:")debugln(input)debugln("solve:")debugln(solve)debugln("greedy:")debugln(greedy)}}}private fun greedy() = Messiah_p674(MOD).exec {TODO()}@Suppress("ClassName", "unused", "FunctionName", "PropertyName")private class Messiah_p674(private val mod: Int) {//////////////////////////////////////////////////// IO//////////////////////////////////////////////////private val input = System.`in`private val buffer = ByteArray(1024)private var pointer = 0private var bufferLength = 0private val sb = StringBuilder()private fun Byte.isPrintable() = this in 33..126private fun Byte.isNumeric() = this in '0'.toByte()..'9'.toByte()private fun Byte.toNumVal() = if (this.isNumeric()) this - '0'.toByte() else error("$this is not numeric")private val lineSeparator: String = System.lineSeparator()private fun hasNextByte(): Boolean {return if (pointer < bufferLength) true else {pointer = 0bufferLength = input.read(buffer)bufferLength > 0}}private fun readByte(): Byte = if (hasNextByte()) buffer[pointer++] else -1private fun skipUnprintable() = run { while (hasNextByte() && !buffer[pointer].isPrintable()) pointer++ }private fun hasNext(): Boolean = run { skipUnprintable() }.run { hasNextByte() }private fun hasNextOrError() = if (!hasNext()) error("has no next element.") else Unitfun readString(): String {hasNextOrError()val sb = StringBuilder()var b = readByte()while (b.isPrintable()) {sb.appendCodePoint(b.toInt())b = readByte()}return sb.toString()}fun readLong(): Long {hasNextOrError()var n = 0Lvar negative = falsevar b = readByte()if (b == '-'.toByte()) {negative = trueb = readByte()}if (!b.isNumeric()) error("$b is not numeric.")while (true) {when {b.isNumeric() -> n = n * 10 + b.toNumVal()b.toInt() == -1 || !b.isPrintable() -> return if (negative) -n else nelse -> error("failed to parse. [n=$n, b=$b]")}b = readByte()}}fun readInt() = readLong().let { if (it in Int.MIN_VALUE..Int.MAX_VALUE) it.toInt() else error("$it is not in range of Int.") }fun readIntAsIndex() = readInt().dec()fun readDouble(): Double {hasNextOrError()var n = 0.0var div = 1.0var negative = falsevar b = readByte()if (b == '-'.toByte()) {negative = trueb = readByte()}do n = n * 10 + b.toNumVal()while (run { b = readByte() }.run { b.isNumeric() })if (b == '.'.toByte()) {while (run { b = readByte() }.run { b.isNumeric() })n += b.toNumVal() / (run { div *= 10 }.run { div })}return if (negative) -n else n}fun readString(size: Int): Array<String> = Array(size) { readString() }@Suppress("UNUSED_PARAMETER")fun readChars(h: Int, w: Int): Array<CharArray> = Array(h) { readString().toCharArray() }fun readLong(size: Int): LongArray = LongArray(size) { readLong() }fun readLong(h: Int, w: Int): Array<LongArray> = Array(h) { readLong(w) }fun readInt(size: Int): IntArray = IntArray(size) { readInt() }fun readInt(h: Int, w: Int): Array<IntArray> = Array(h) { readInt(w) }fun readIntAsIndex(size: Int): IntArray = IntArray(size) { readIntAsIndex() }fun readIntAsIndex(h: Int, w: Int): Array<IntArray> = Array(h) { readIntAsIndex(w) }fun readDouble(size: Int): DoubleArray = DoubleArray(size) { readDouble() }fun readDouble(h: Int, w: Int): Array<DoubleArray> = Array(h) { readDouble(w) }fun readBooleanWithSeparator(size: Int, trueElement: String): BooleanArray =BooleanArray(size) { readString() == trueElement }fun readBooleanWithSeparator(h: Int, w: Int, trueElement: String): Array<BooleanArray> =Array(h) { readBooleanWithSeparator(w, trueElement) }@Suppress("UNUSED_PARAMETER")fun readBooleanWithoutSeparator(size: Int, trueElement: Char): BooleanArray =readString().map { it == trueElement }.toBooleanArray()fun readBooleanWithoutSeparator(h: Int, w: Int, trueElement: Char): Array<BooleanArray> =Array(h) { readBooleanWithoutSeparator(w, trueElement) }fun println(): Unit = run { sb.append(lineSeparator) }fun print(any: Any): Unit = run { sb.append(any.toString()) }fun println(any: Any): Unit = run { sb.append(any.toString() + lineSeparator) }fun flush() = run { kotlin.io.println(sb); sb.clear() }fun debug(any: Any): Unit = run { if (localEnv) System.err.print(any) }fun debugln(any: Any): Unit = run { if (localEnv) System.err.println(any) }fun debugln(): Unit = run { if (localEnv) System.err.println() }fun debugExec(action: () -> Unit): Unit = run { if (localEnv) action() }fun exec(action: Messiah_p674.() -> Unit) {var t: Throwable? = nullThread(null, { action() }, "solve", 128 * 1024 * 1024).apply { setUncaughtExceptionHandler { _, t1 -> t = t1 } }.apply { start() }.join()t?.let { throw it }kotlin.io.print(sb)}fun readLine(): Nothing = error("readLine is disabled.")//////////////////////////////////////////////////// MOD//////////////////////////////////////////////////private val modIsPrime: Boolean = MOD.toBigInteger().isProbablePrime(100)fun Long.invertMod(): Long = if (modIsPrime) this.powMod(MOD - 2L) else invGcd(this).secondfun Long.safeMod(): Long = (this % MOD).let { if (it < 0) it + MOD else it }fun Long.plusMod(other: Long): Long = this.plus(other).safeMod()fun Long.minusMod(other: Long): Long = this.minus(other).safeMod()fun Long.timesMod(other: Long): Long = this.times(other).safeMod()fun Long.divMod(other: Long): Long = this.times(other.invertMod()).safeMod()fun Long.powMod(p: Long): Long {var x = this % MODvar y = pvar result = 1Lwhile (y > 0) {if (y % 2 == 1L) result = (result * x) % MODy = y shr 1x = (x * x) % MOD}return result}fun Long.powMod(p: Long, m: Int): Long {var x = this % mvar y = pvar result = 1Lwhile (y > 0) {if (y % 2 == 1L) result = (result * x) % my = y shr 1x = (x * x) % m}return result}fun invGcd(a: Long): Pair<Long, Long> {val am = a.safeMod()if (a == 0L) return MOD.toLong() to 0Lvar s = MOD.toLong()var t = amvar m0 = 0Lvar m1 = 1Lwhile (t != 0L) {val u = s / ts -= t * um0 -= m1 * uvar temp = ss = tt = temptemp = m0m0 = m1m1 = temp}if (m0 < 0) m0 += MOD / sreturn s to m0}//////////////////////////////////////////////////// Misc///////////////////////////////////////////////////*** `n.indices()` is sugar syntax of `0 until n`.*/val Int.indices: IntRange get() = 0 until this/*** `[index] in [this]` is sugar syntax of `index in 0 until [this]`.*/operator fun Int.contains(index: Int): Boolean = index in this.indices/*** `[this].mapIndices { transform }` is sugar syntax of `(0 until [this]).map{ transform(it) }`.*/inline fun <R> Int.mapIndices(transform: (Int) -> R): List<R> = this.indices.map(transform)/*** `[this].mapIndices(x) { transform }` is sugar syntax of* `(0 until [this]).map{ y1-> (0 until [x]).map { x1-> transform(y1,x1) } }`.*/inline fun <R> Int.mapIndices(x: Int, transform: (Int, Int) -> R): List<List<R>> =this.mapIndices { y1 -> x.mapIndices { x1 -> transform(y1, x1) } }/*** `[this].mapIndices(x) { transform }` is sugar syntax of* `(0 until [this]).map{ y1-> (0 until [x]).map { x1-> transform(y1,x1) } }`.*/inline fun <R> Int.flatMapIndices(x: Int, transform: (Int, Int) -> R): List<R> =this.indices.flatMap { y1 -> x.mapIndices { x1 -> transform(y1, x1) } }/*** `[this].forEachIndices { transform }` is sugar syntax of `(0 until [this]).map{ transform(it) }`.*/inline fun Int.forEachIndices(transform: (Int) -> Unit): Unit = this.indices.forEach(transform)/*** `[this].forEachIndices(x) { transform }` is sugar syntax of* `(0 until [this]).map{ y1-> (0 until [x]).map { x1-> transform(y1,x1) } }`.*/inline fun Int.forEachIndices(x: Int, transform: (Int, Int) -> Unit): Unit =this.forEachIndices { y1 -> x.forEachIndices { x1 -> transform(y1, x1) } }/*** get characters numeric value.* e.g.: '0' to 0*/fun Char.toNumericValue(): Int = this - '0'fun Char.caseToIndexedValue(): Int = this - 'a'fun String.toPoweredLong(p: Int): Long {check(this.isNotBlank())if (this[0] == '-') return -this.drop(1).toPoweredLong(p)var mulI = 1Lrepeat(p) { mulI *= 10 }val i = this.indexOf('.').takeIf { it != -1 } ?: return this.toLong() * mulIvar mulD = 1Lrepeat(p - this.length + i + 1) { mulD *= 10 }return this.slice(0 until i).toLong() * mulI + this.slice(i + 1..this.lastIndex).toLong() * mulD}/*** make triple. e.g.:`1 to 2 to 3`*/infix fun <A, B, C> Pair<A, B>.to(c: C): Triple<A, B, C> = Triple(this.first, this.second, c)fun YesNo(b: Boolean): String = if (b) Yes else Noval Yes = "Yes"val No = "No"fun YES_NO(b: Boolean): String = if (b) YES else NOval YES = "YES"val NO = "NO"fun IntArray.swap(a: Int, b: Int): Unit = run { val temp = this[a]; this[a] = this[b]; this[b] = temp }fun LongArray.swap(a: Int, b: Int): Unit = run { val temp = this[a]; this[a] = this[b]; this[b] = temp }fun CharArray.swap(a: Int, b: Int): Unit = run { val temp = this[a]; this[a] = this[b]; this[b] = temp }fun <T> Array<T>.swap(a: Int, b: Int): Unit = run { val temp = this[a]; this[a] = this[b]; this[b] = temp }fun <T> MutableList<T>.swap(a: Int, b: Int): Unit = run { val temp = this[a]; this[a] = this[b]; this[b] = temp }fun IntArray.changeMinOf(i: Int, v: Int): Boolean = run { if (this[i] > v) run { this[i] = v; true } else false }fun IntArray.changeMaxOf(i: Int, v: Int): Boolean = run { if (this[i] < v) run { this[i] = v; true } else false }fun LongArray.changeMinOf(i: Int, v: Long): Boolean = run { if (this[i] > v) run { this[i] = v; true } else false }fun LongArray.changeMaxOf(i: Int, v: Long): Boolean = run { if (this[i] < v) run { this[i] = v; true } else false }fun Array<IntArray>.changeMinOf(i: Int, j: Int, v: Int): Boolean = run { this[i].changeMinOf(j, v) }fun Array<IntArray>.changeMaxOf(i: Int, j: Int, v: Int): Boolean = run { this[i].changeMaxOf(j, v) }fun Array<LongArray>.changeMinOf(i: Int, j: Int, v: Long): Boolean = run { this[i].changeMinOf(j, v) }fun Array<LongArray>.changeMaxOf(i: Int, j: Int, v: Long): Boolean = run { this[i].changeMaxOf(j, v) }/*** same usage as `IntArray.scan`, but it will faster than that.*/inline fun IntArray.scanArray(initial: Int, operation: (acc: Int, Int) -> Int): IntArray {val accumulator = IntArray(this.size + 1).apply { this[0] = initial }for (i in this.indices) accumulator[i + 1] = operation(accumulator[i], this[i])return accumulator}/*** same usage as `LongArray.scan`, but it will faster than that.*/inline fun LongArray.scanArray(initial: Long, operation: (acc: Long, Long) -> Long): LongArray {val accumulator = LongArray(this.size + 1).apply { this[0] = initial }for (i in this.indices) accumulator[i + 1] = operation(accumulator[i], this[i])return accumulator}/*** same usage as `IntArray.scanReduce`, but it will faster than that.*/inline fun IntArray.scanReduceArray(operation: (acc: Int, Int) -> Int): IntArray {val accumulator = IntArray(this.size).apply { this[0] = this@scanReduceArray[0] }for (i in 1..this.lastIndex) accumulator[i] = operation(accumulator[i - 1], this[i])return accumulator}/*** same usage as `LongArray.scanReduce`, but it will faster than that.*/inline fun LongArray.scanReduceArray(operation: (acc: Long, Long) -> Long): LongArray {val accumulator = LongArray(this.size).apply { this[0] = this@scanReduceArray[0] }for (i in 1..this.lastIndex) accumulator[i] = operation(accumulator[i - 1], this[i])return accumulator}}// endregion kokomade template dayo (^o^)