結果
| 問題 |
No.973 余興
|
| コンテスト | |
| ユーザー |
yakamoto
|
| 提出日時 | 2020-01-18 14:19:41 |
| 言語 | Kotlin (2.1.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 2,969 bytes |
| コンパイル時間 | 17,329 ms |
| コンパイル使用メモリ | 455,444 KB |
| 実行使用メモリ | 147,040 KB |
| 最終ジャッジ日時 | 2024-06-27 14:28:50 |
| 合計ジャッジ時間 | 95,302 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 25 WA * 18 TLE * 11 |
ソースコード
import kotlin.math.max
import kotlin.math.min
val MOD = 1_000_000_007
fun main() {
val (N, X) = readInts()
val A = readInts()
if (N == 1) {
println("B")
return
}
val dpL = Array(N){SegmentTree(N - it, true){a, b -> a and b}}
val dpR = Array(N){SegmentTree(it + 1, true){a, b -> a and b}}
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) {
val r = l + len - 1
val win = !dpL[l].query(max(0, len-1-mxL[r]), len-1) or
!dpR[r].query(max(0, len-1-mxR[l]), len-1)
dpL[l].update(len - 1, win)
dpR[r].update(len - 1, win)
}
}
if (dpL[0].query(N-1, N)) println("A")
else println("B")
}
class SegmentTree(n: Int, val zero: Boolean, val f: (Boolean, Boolean) -> Boolean) {
private val N =
if (Integer.highestOneBit(n) == n) n
else Integer.highestOneBit(n) shl 1
private val dat = BooleanArray(2 * N){zero}
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