raahii.meのブログのロゴ画像

ウェブログ

約数の全列挙の高速化

ある整数 nn の約数を全て探すとき,普通は 11 から nn までを走査するfor文で1つ1つ約数判定を行う.この場合の計算量は O(n)O(n) であり,制約が n109n \leq 10^9 のような競プロのコンテストでは通常通らないと考える.

しかし, n=a×bn=a \times b を満たすような整数ペア a,b(ab)a, b (a \leq b) を考えると, ana \leq\sqrt{n} を満たすため,これを利用することで O(n)O(\sqrt{n}) で約数を全列挙できる.

package main

import (
	"fmt"
)

func main() {
	var n int
	fmt.Scan(&n)

	for a := 1; a*a <= n; a++ {
		if n%a != 0 {
			continue
		}

		b := n / a
		fmt.Println(a)
		fmt.Println(b)
	}
}

ちなみにこれは Atcoder ABC112 D で使用した.実はGoで書くと nn10910^9 でも通るのだけど,まぁ増やされたらそれまでなのでまとめてみた.