[R67C] 排列
- 难度 普及
- 时限 1s
- 空限 512m
- 模拟
数据规模:。
思路
矩阵第 行是把排列 连续作用 次的结果,即 。由递推 ,可以在已知第 行时用 一次性算出整行。
由于 都不超过 ,直接从第 行逐层模拟到第 行即可。在过程中,当层数等于 时把当前行存为 、等于 时存为 ,最后逐位比较 与 的字典序输出符号。
空间上只保留「上一层」与「当前层」两个数组(滚动数组),不需要存整个矩阵。
复杂度:时间 ,空间 。
仓颉实现
import std.env.*
import std.convert.*
main(): Int64 {
let reader = getStdIn()
let n = Int64.parse(reader.readln().getOrThrow().split(" ", removeEmpty: true)[0])
let p = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ s => Int64.parse(s) })
let xy = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ s => Int64.parse(s) })
let x = xy[0]
let y = xy[1]
let nn = n
var cur = Array<Int64>(nn, { i => p[i] })
var vx: Array<Int64> = Array<Int64>(nn, { _ => 0 })
var vy: Array<Int64> = Array<Int64>(nn, { _ => 0 })
var hi = x
if (y > hi) {
hi = y
}
if (x == 1) {
var i = 0
while (i < nn) {
vx[i] = cur[i]
i += 1
}
}
if (y == 1) {
var i = 0
while (i < nn) {
vy[i] = cur[i]
i += 1
}
}
var k = 2
while (k <= hi) {
let prev = cur
cur = Array<Int64>(nn, { i => prev[p[i] - 1] })
if (k == x) {
var i = 0
while (i < nn) {
vx[i] = cur[i]
i += 1
}
}
if (k == y) {
var i = 0
while (i < nn) {
vy[i] = cur[i]
i += 1
}
}
k += 1
}
var i = 0
var res = "="
while (i < nn) {
if (vx[i] < vy[i]) {
res = "<"
break
} else if (vx[i] > vy[i]) {
res = ">"
break
}
i += 1
}
println(res)
return 0
}
要点:
- ,由于 ,数组按下标取值时要减 转为 基下标。
- 用滚动数组只保留相邻两层,把空间从 压到 。
- 逐位比较时,第一次遇到不等的元素即可确定大小关系;全部相等则输出
=。