From 203a5bbc5ec4bacc9b6effd14707ad1369c44c52 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sun, 16 Mar 2025 03:30:25 +0200 Subject: [PATCH] Improved tasks 3161, 3327 --- .../s3161_block_placement_queries/Solution.kt | 162 ++++++++++-------- .../Solution.kt | 121 +++++++------ 2 files changed, 152 insertions(+), 131 deletions(-) diff --git a/src/main/kotlin/g3101_3200/s3161_block_placement_queries/Solution.kt b/src/main/kotlin/g3101_3200/s3161_block_placement_queries/Solution.kt index cc983728d..5b64e0daf 100644 --- a/src/main/kotlin/g3101_3200/s3161_block_placement_queries/Solution.kt +++ b/src/main/kotlin/g3101_3200/s3161_block_placement_queries/Solution.kt @@ -1,104 +1,118 @@ package g3101_3200.s3161_block_placement_queries // #Hard #Array #Binary_Search #Segment_Tree #Binary_Indexed_Tree -// #2024_05_30_Time_1701_ms_(100.00%)_Space_174.7_MB_(33.33%) +// #2025_03_16_Time_100_ms_(100.00%)_Space_144.97_MB_(43.75%) import kotlin.math.max class Solution { - private class Seg private constructor(private val start: Int, private val end: Int) { - private var min = 0 - private var max = 0 - private var len = 0 - private var obstacle = false - private lateinit var left: Seg - private lateinit var right: Seg - - init { - if (start < end) { - val mid = start + ((end - start) shr 1) - left = Seg(start, mid) - right = Seg(mid + 1, end) - refresh() + fun getResults(queries: Array): List { + val m = queries.size + val pos = IntArray(m + 1) + var size = 0 + pos[size++] = 0 + var max = 0 + for (q in queries) { + max = max(max.toDouble(), q[1].toDouble()).toInt() + if (q[0] == 1) { + pos[size++] = q[1] } } + pos.sort(0, size) + max++ + val left = UnionFind(max + 1) + val right = UnionFind(max + 1) + val bit = BIT(max) + initializePositions(size, pos, bit, left, right, max) + return listOf(*getBooleans(queries, m, size, left, right, bit)) + } - fun set(i: Int) { - if (i < start || i > end) { - return - } else if (i == start && i == end) { - obstacle = true - max = start - min = max - return + private fun initializePositions( + size: Int, + pos: IntArray, + bit: BIT, + left: UnionFind, + right: UnionFind, + max: Int, + ) { + for (i in 1.., + m: Int, + size: Int, + left: UnionFind, + right: UnionFind, + bit: BIT, + ): Array { + val ans = Array(m - size + 1) { false } + var index = ans.size - 1 + for (i in m - 1 downTo 0) { + val q = queries[i] + val x = q[1] + val pre = left.find(x - 1) + if (q[0] == 1) { + val next = right.find(x + 1) + left.parent[x] = pre + right.parent[x] = next + bit.update(next, next - pre) } else { - len = end - start + val maxGap = max(bit.query(pre).toDouble(), (x - pre).toDouble()).toInt() + ans[index--] = maxGap >= q[2] } } + return ans + } - fun max(n: Int, t: IntArray) { - if (end <= n) { - t[0] = max(t[0], len) - if (obstacle) { - t[1] = max - } - return - } - left.max(n, t) - if (!right.obstacle || right.min >= n) { - return + private class BIT(var n: Int) { + var tree: IntArray = IntArray(n) + + fun update(i: Int, v: Int) { + var i = i + while (i < n) { + tree[i] = max(tree[i].toDouble(), v.toDouble()).toInt() + i += i and -i } - t[0] = max(t[0], (right.min - t[1])) - right.max(n, t) } - companion object { - fun init(n: Int): Seg { - return Seg(0, n) + fun query(i: Int): Int { + var i = i + var result = 0 + while (i > 0) { + result = max(result.toDouble(), tree[i].toDouble()).toInt() + i = i and i - 1 } + return result } } - fun getResults(queries: Array): List { - var max = 0 - for (i in queries) { - max = max(max, i[1]) + private class UnionFind(n: Int) { + val parent: IntArray = IntArray(n) + + init { + for (i in 1.. = ArrayList(queries.size) - for (i in queries) { - if (i[0] == 1) { - root.set(i[1]) - } else { - val t = IntArray(2) - root.max(i[1], t) - res.add(max(t[0], (i[1] - t[1])) >= i[2]) + fun find(x: Int): Int { + if (parent[x] != x) { + parent[x] = find(parent[x]) } + return parent[x] } - return res } } diff --git a/src/main/kotlin/g3301_3400/s3327_check_if_dfs_strings_are_palindromes/Solution.kt b/src/main/kotlin/g3301_3400/s3327_check_if_dfs_strings_are_palindromes/Solution.kt index ed5c630ae..a8b5f8209 100644 --- a/src/main/kotlin/g3301_3400/s3327_check_if_dfs_strings_are_palindromes/Solution.kt +++ b/src/main/kotlin/g3301_3400/s3327_check_if_dfs_strings_are_palindromes/Solution.kt @@ -1,75 +1,82 @@ package g3301_3400.s3327_check_if_dfs_strings_are_palindromes // #Hard #Array #String #Hash_Table #Depth_First_Search #Tree #Hash_Function -// #2024_10_22_Time_165_ms_(100.00%)_Space_88.9_MB_(66.67%) +// #2025_03_16_Time_86_ms_(100.00%)_Space_93.26_MB_(80.00%) import kotlin.math.min class Solution { - private val e: MutableList> = ArrayList>() - private val stringBuilder = StringBuilder() - private var s: String? = null - private var now = 0 - private var n = 0 - private lateinit var l: IntArray - private lateinit var r: IntArray - private lateinit var p: IntArray - private lateinit var c: CharArray + private var time = 0 + private lateinit var cs: ByteArray + private lateinit var graph: Array - private fun dfs(x: Int) { - l[x] = now + 1 - for (v in e[x]) { - dfs(v) + fun findAnswer(parent: IntArray, s: String): BooleanArray { + val n = s.length + cs = s.toByteArray() + graph = arrayOfNulls(n) + val childCount = IntArray(n) + for (i in 1.. localR) { - localR = p[j] + j - 1 - mid = j - } - ++j + for (i in 1..= r - l + 1 } + return ans } - fun findAnswer(parent: IntArray, s: String): BooleanArray { - n = parent.size - this.s = s - for (i in 0 until n) { - e.add(ArrayList()) + private fun dfs(u: Int, dfsStr: ByteArray, start: IntArray, end: IntArray) { + start[u] = time + for (v in graph[u]!!) { + dfs(v, dfsStr, start, end) } - for (i in 1 until n) { - e[parent[i]].add(i) + dfsStr[time] = cs[u] + end[u] = time++ + } + + private fun getRadius(cs: ByteArray): IntArray { + val n = cs.size + val t = ByteArray(2 * n + 3) + var m = 0 + t[m++] = '@'.code.toByte() + t[m++] = '#'.code.toByte() + for (c in cs) { + t[m++] = c + t[m++] = '#'.code.toByte() } - l = IntArray(n) - r = IntArray(n) - dfs(0) - c = CharArray(2 * n + 10) - p = IntArray(2 * n + 10) - matcher() - val ans = BooleanArray(n) - for (i in 0 until n) { - val mid = (2 * r[i] - 2 * l[i] + 1) / 2 + 2 * l[i] - ans[i] = p[mid] - 1 >= r[i] - l[i] + 1 + t[m++] = '$'.code.toByte() + val lens = IntArray(m) + var center = 0 + var right = 0 + for (i in 2..