ABC 052 C - Factors of Factorial のメモ
解いてみました。
考察
階乗ですね。最大だと1000の階乗で、とてつもない数になるので実際に求めるわけにもいきません。
しかし、
それでわかったのは、
なので、素数の場合は答えを倍にして、素数でない場合は倍にした後に重複する数の個数分引くという操作で求められるのかなと考えました。
しかし、重複する数の個数を定数時間で求められる方法を見つけられず。一応もう少し進んで、
そもそも約数の個数の求め方なんて普通に定石があるのではとようやく思い至って調べました。ググるとやはり普通に見つかって、
たとえば360を素因数分解すると
これで求められそうです。
ただ、階乗を求めてから素因数分解はもちろん無理です。しかし1から
実装
fun main() {
val n = readLine()!!.toInt()
val primeFactorials = (1..n).map { primeFactorial(it.toLong()) }
val map = mutableMapOf<Long, Long>()
val mod = 1000000007
for(pfs in primeFactorials) {
for(pf in pfs) {
map[pf.first] = map.getOrDefault(pf.first, 0) + pf.second
}
}
var ans = 1L
for((_, value) in map) {
ans = (ans % mod) * ((value + 1) % mod) % mod
}
println(ans % mod)
}
fun primeFactorial(paramN: Long): List<Pair<Long, Long>> {
val result = mutableListOf<Pair<Long, Long>>()
var n = paramN
var a = 2L
while(a * a <= n) {
if(n % a != 0L) {
a++
continue
}
var ex = 0L
while (n % a == 0L) {
ex++
n /= a
}
result.add(a to ex)
a++
}
if(n != 1L) {
result.add(n to 1)
}
return result
}
素因数分解は以前使ったものを流用しました。
内容として上で書いた通りですが、オーバーフローしないように随時modをとる必要があります。
(執筆時間: 27分2秒)
Discussion