https://coderun.yandex.ru/problem/bonsai-tree/description Не определена

Решение

import java.io.DataInputStream
import java.io.BufferedWriter
import java.io.OutputStreamWriter

private const val MOD = 1_000_000_007
private const val MAXX = 1_000_000

class FastReader {
    private val din = DataInputStream(System.`in`)
    private val buf = ByteArray(1 shl 16)
    private var ptr = 0
    private var buflen = 0

    private fun read(): Int {
        if (buflen == -1) return -1
        if (ptr >= buflen) {
            buflen = din.read(buf)
            ptr = 0
            if (buflen <= 0) return -1
        }
        return buf[ptr++].toInt()
    }

    fun nextInt(): Int {
        var c = read()
        while (c != -1 && c <= ' '.code) c = read()
        if (c == -1) return -1
        var neg = false
        if (c == '-'.code) {
            neg = true
            c = read()
        }
        var x = 0
        while (c >= '0'.code && c <= '9'.code) {
            x = x * 10 + (c - '0'.code)
            c = read()
        }
        return if (neg) -x else x
    }
}

fun modPow(base: Long, exp: Int): Long {
    var b = base % MOD
    var e = exp
    var result = 1L
    while (e > 0) {
        if (e and 1 == 1) result = (result * b) % MOD
        b = (b * b) % MOD
        e = e ushr 1
    }
    return result
}

fun main() {
    val reader = FastReader()
    val bw = BufferedWriter(OutputStreamWriter(System.out))

    val n = reader.nextInt()
    val q = reader.nextInt()

    val parent = IntArray(n + 1)
    for (i in 2..n) {
        parent[i] = reader.nextInt()
    }

    val children = Array(n + 1) { IntArray(2) }
    val childCnt = IntArray(n + 1)
    for (v in 2..n) {
        val p = parent[v]
        children[p][childCnt[p]] = v
        childCnt[p]++
    }

    val spf = IntArray(MAXX + 1)
    for (i in 2..MAXX) {
        if (spf[i] == 0) {
            var j = i
            while (j <= MAXX) {
                if (spf[j] == 0) spf[j] = i
                j += i
            }
        }
    }

    val factorMap = arrayOfNulls<HashMap<Int, Int>>(n + 1)
    val interest = LongArray(n + 1) { 1L }

    val changed = mutableListOf<Pair<Int, Int>>()
    val nextChanged = mutableListOf<Pair<Int, Int>>()

    repeat(q) {
        when (reader.nextInt()) {
            1 -> {
                var v = reader.nextInt()
                var x = reader.nextInt()

                changed.clear()
                while (x > 1) {
                    val p = spf[x]
                    var cnt = 0
                    while (x % p == 0) {
                        x /= p
                        cnt++
                    }
                    var fm = factorMap[v]
                    if (fm == null) {
                        fm = HashMap()
                        factorMap[v] = fm
                    }
                    val oldExp = fm.getOrDefault(p, 0)
                    val newExp = oldExp + cnt
                    fm[p] = newExp
                    interest[v] = interest[v] * modPow(p.toLong(), cnt) % MOD
                    changed.add(p to newExp)
                }

                var child = v
                var cur = parent[v]
                while (cur != 0 && changed.isNotEmpty()) {
                    nextChanged.clear()
                    for ((p, expChild) in changed) {
                        val (l, r) = children[cur]
                        val sib = if (l == child) r else l
                        val expSib = factorMap[sib]?.getOrDefault(p, 0) ?: 0
                        val oldCur = factorMap[cur]?.getOrDefault(p, 0) ?: 0
                        val newCur = if (expChild < expSib) expChild else expSib
                        if (newCur > oldCur) {
                            var cm = factorMap[cur]
                            if (cm == null) {
                                cm = HashMap()
                                factorMap[cur] = cm
                            }
                            cm[p] = newCur
                            interest[cur] = interest[cur] * modPow(p.toLong(), newCur - oldCur) % MOD
                            nextChanged.add(p to newCur)
                        }
                    }
                    child = cur
                    cur = parent[cur]
                    changed.clear()
                    changed.addAll(nextChanged)
                }
            }
            else -> {
                val v = reader.nextInt()
                bw.write(interest[v].toString())
                bw.newLine()
            }
        }
    }

    bw.flush()
}