[R7C] 二维gcd和
数据规模:。
思路
把 作为公因式提出,原式可化为两个独立的一维和之积:
记 。按最大公因数分组: 当且仅当 且 ,这样的 恰有 个,所以
用欧拉筛预处理 ,再枚举 的因子 (只枚举到 ,因子成对出现)即可 求出 。最后把 与 相乘并对 取模。
复杂度:时间 ,空间 。
仓颉实现
查看仓颉实现
import std.collection.*
import std.convert.*
import std.env.*
func gcdSum(x: Int64, phi: Array<Int64>): Int64 {
var res: Int64 = 0
var d: Int64 = 1
while (d * d <= x) {
if (x % d == 0) {
res = res + d * phi[x / d]
if (d * d != x) {
res = res + (x / d) * phi[d]
}
}
d = d + 1
}
return res
}
main() {
let reader = getStdIn()
let line = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ p => Int64.parse(p) })
let n = line[0]
let m = line[1]
let maxv = if (n > m) { n } else { m }
let phi = Array<Int64>(maxv + 1, { _ => 0 })
let isComp = Array<Bool>(maxv + 1, { _ => false })
let primes = ArrayList<Int64>()
phi[1] = 1
for (i in 2..(maxv + 1)) {
if (!isComp[i]) {
primes.add(i)
phi[i] = i - 1
}
for (p in primes) {
if (i * p > maxv) {
break
}
isComp[i * p] = true
if (i % p == 0) {
phi[i * p] = phi[i] * p
break
} else {
phi[i * p] = phi[i] * (p - 1)
}
}
}
let MOD: Int64 = 998244353
println(gcdSum(n, phi) % MOD * (gcdSum(m, phi) % MOD) % MOD)
}