[R38A]不为倍数
对于 的数据,,,。
思路
的范围很小(最多 ),可以直接开一个布尔数组 bad[1..X],表示每个位置是否是某个 的倍数。
对每个 ,把它的所有不超过 的倍数 逐一标记为 true。最后数 到 中 bad 为 false 的位置个数即为答案。
几点细节:
- 可能为 ,此时没有第二行输入,直接输出 即可,读入时要判断后再读数组。
- 中可能出现重复或 ( 会把所有数标记掉),无需特殊处理,重复标记只是多写几次相同位置。
- 每个位置只被标记一次,重复标记不会影响正确性。
复杂度
- 时间:每个 最多标记 个位置,总和不超过 ;最坏情况下(全部 )为 ,整体上界为 。
- 空间: 的布尔数组。
仓颉实现
import std.console.*
import std.convert.*
main(): Int64 {
let reader = Console.stdIn
let first = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ p: String => Int64.parse(p) })
let n = first[0]
let X = first[1]
let bad = Array<Bool>(X + 1, { _ => false })
if (n > 0) {
let a = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ p: String => Int64.parse(p) })
for (ai in a) {
var k = ai
while (k <= X) {
bad[k] = true
k += ai
}
}
}
var ans = 0
var i = 1
while (i <= X) {
if (!bad[i]) {
ans++
}
i++
}
println(ans)
return 0
}