結果
| 問題 |
No.973 余興
|
| コンテスト | |
| ユーザー |
yakamoto
|
| 提出日時 | 2020-01-18 15:20:12 |
| 言語 | Kotlin (2.1.0) |
| 結果 |
AC
|
| 実行時間 | 3,081 ms / 4,000 ms |
| コード長 | 3,242 bytes |
| コンパイル時間 | 18,298 ms |
| コンパイル使用メモリ | 465,228 KB |
| 実行使用メモリ | 146,156 KB |
| 最終ジャッジ日時 | 2024-06-27 15:11:09 |
| 合計ジャッジ時間 | 115,644 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 54 |
コンパイルメッセージ
Main.kt:82:11: warning: expected performance impact from inlining is insignificant. Inlining works best for functions with parameters of functional types
private inline fun f(a: Boolean, b: Boolean) = a and b
^
ソースコード
import kotlin.math.max
import kotlin.math.min
val MOD = 1_000_000_007
fun main() {
val (N, X) = readInts()
val A = readInts()
val dpL = Array(N){SegmentTree(N - it, true)}
val dpR = Array(N){SegmentTree(it + 1, true)}
for (i in 0 until N) {
// 1個だけ残ってる場合はlose
dpL[i].update(0, false)
dpR[i].update(0, false)
}
val mxR = run {
val res = IntArray(N)
var sum = 0L
var r = N - 1
for (l in N - 1 downTo 0) {
sum += A[l]
while (r > l && sum > X) {
sum -= A[r]
r--
}
res[l] = r - l + 1
}
res
}
debug(mxR)
val mxL = run {
val res = IntArray(N)
var sum = 0L
var l = 0
for (r in 0 until N) {
sum += A[r]
while (l < r && sum > X) {
sum -= A[l]
l++
}
res[r] = r - l + 1
}
res
}
debug(mxL)
for (len in 2 until N + 1) {
for (l in 0 until N - len + 1) {
val r = l + len - 1
val win = !dpL[l].query(max(0, len-mxL[r]-1), len-1) or
!dpR[r].query(max(0, len-mxR[l]-1), len-1)
debug{"$l $r $win"}
dpL[l].update(len - 1, win)
dpR[r].update(len - 1, win)
}
}
if(isDebug) {
for (l in 0 until N) {
val flags = mutableListOf<Boolean>()
for (r in l until N) {
val len = r-l
assert(dpL[l].query(len, len+1) == dpR[r].query(len, len+1))
flags.add(dpR[r].query(len, len+1))
}
debug(flags.toBooleanArray())
}
}
if (dpL[0].query(N-1, N)) println("A")
else println("B")
}
class SegmentTree(n: Int, val zero: Boolean) {
private val N =
if (Integer.highestOneBit(n) == n) n
else Integer.highestOneBit(n) shl 1
private val dat = BooleanArray(2 * N){zero}
private inline fun f(a: Boolean, b: Boolean) = a and b
fun update(i: Int, a: Boolean) {
var ix = i + N
dat[ix] = a
while(ix > 1) {
dat[ix shr 1] = f(dat[ix], dat[ix xor 1])
ix = ix shr 1
}
}
/**
* [a, b)
*/
fun query(a: Int, b: Int): Boolean {
var res: Boolean = zero
var left = a + N
var right = b - 1 + N
while(left <= right) {
if ((left and 1) == 1) res = f(res, dat[left])
if ((right and 1) == 0) res = f(res, dat[right])
left = (left + 1) shr 1 // 右の子供なら右の親に移動
right = (right - 1) shr 1 // 左の子供なら左の親に移動
}
return res
}
}
private val isDebug = try {
// なんか本番でエラーでる
System.getenv("MY_DEBUG") != null
} catch (t: Throwable) {
false
}
private fun readLn() = readLine()!!
private fun readStrings() = readLn().split(" ")
private fun readInts() = readStrings().map { it.toInt() }.toIntArray()
private fun readLongs() = readStrings().map { it.toLong() }.toLongArray()
private inline fun debug(msg: () -> String) {
if (isDebug) System.err.println(msg())
}
private fun debug(a: LongArray) {
debug{a.joinToString(" ")}
}
private fun debug(a: IntArray) {
debug{a.joinToString(" ")}
}
private fun debug(a: BooleanArray) {
debug{a.map{if(it) 1 else 0}.joinToString("")}
}
private fun debugDim(A: Array<IntArray>) {
if (isDebug) {
for (a in A) {
debug(a)
}
}
}
yakamoto