Skip to content

Instantly share code, notes, and snippets.

@elizarov
Created December 26, 2018 19:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elizarov/7bc473066f03db749d8357917db44d4c to your computer and use it in GitHub Desktop.
Save elizarov/7bc473066f03db749d8357917db44d4c to your computer and use it in GitHub Desktop.
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*
// Solution for http://codeforces.com/problemset/problem/767/C
fun main() {
val n = readLine()!!.toInt()
val a = IntArray(n + 1)
val t = IntArray(n + 1)
for (i in 1..n) {
val (ai, ti) = readLine()!!.split(" ").map { it.toInt() }
a[i] = ai
t[i] = ti
}
println(solveGarlandRec(a, t)?.joinToString(" ") ?: "-1")
}
fun solveGarlandRec(a: IntArray, t: IntArray): List<Int>? {
val total = t.sum()
if (total % 3 != 0) return null
val children = a.asSequence().withIndex().drop(1).groupBy({ it.value }, { it.index })
val expected = total / 3
val result = ArrayList<Int>()
suspend fun Rec.dfs(i: Int): Int {
var iSum = t[i]
val list = children[i] ?: return iSum
for (j in list) {
val jSum = rec { dfs(j) }
if (jSum == expected && result.size < 2) {
result += j
} else {
iSum += jSum
}
}
return iSum
}
Rec { dfs(children.getValue(0).single()) }
return result.takeIf { it.size == 2 }
}
@RestrictsSuspension
class Rec(block: suspend Rec.() -> Unit) {
private var cur: (() -> Unit)? = null
init {
var ex: Throwable? = null
block.startCoroutine(this, Continuation(EmptyCoroutineContext) { ex = it.exceptionOrNull() })
while (true) { cur?.invoke() ?: break }
ex?.let { throw it }
}
suspend fun <T> rec(block: suspend Rec.() -> T): T = suspendCoroutineUninterceptedOrReturn { cont ->
cur = { block.startCoroutine(this, cont) }
COROUTINE_SUSPENDED
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment