130 likes | 212 Views
講義 1: 素数と累積和. @ kagamiz (Jayson Sho Toma ). 素数とは?. 1 とその数自身以外に約数を持たない数 ただし 1 は 素数ではない なぜか考えてみよう 素数ではない数を 合成数 という. 素数判定. 数 n が素数かどうか判定したい 試し割りをしていく方法 最悪 n に比例する時間がかかる n = 1 の処理に注意 素数の性質を使う方法. 素数判定. 数 n が素数かどうか判定したい 試し割りをしていく方法 素数の性質を使う方法 √ n までの 素数で試し割りを行う
E N D
講義 1:素数と累積和 @kagamiz (Jayson ShoToma)
素数とは? • 1 とその数自身以外に約数を持たない数 • ただし 1 は素数ではない • なぜか考えてみよう • 素数ではない数を合成数という
素数判定 • 数 nが素数かどうか判定したい • 試し割りをしていく方法 • 最悪 nに比例する時間がかかる • n = 1 の処理に注意 • 素数の性質を使う方法
素数判定 • 数 nが素数かどうか判定したい • 試し割りをしていく方法 • 素数の性質を使う方法 • √nまでの素数で試し割りを行う • 最悪 √nに比例する時間 (さっきより速い) • 何故これでいいのか?
√nまでの試し割り:証明 • nが合成数であれば, 定義より n = a × b と表せる. いま a≧ b⇒ a × b≧ b × b = b^2. よって n≧ b^2, √n≧ bとなり, √n以下の約数があることが証明された.//
実行時間とプログラムの計算量 • ループの回数が大体 10^8 (1 億) で 1 秒 • 10^9 回の処理は約 10 秒程度かかる! • 10^8 回以下程度の処理を心がけよう • 詳しい話は「計算量 オーダー記法」で ググる or 先輩達に聞こう
素数の個数を数える • 区間 [l, r] の素数の個数を数えよう! • [l, r] の素数を試し割りで毎回数えると, √l + √(l + 1) + … + √r≦ (r – l + 1)√r • [1, 10^6] の素数を試し割りで数えると,10^9 回くらいの計算に • 実際はもっと速いため KCS でもこれで OK
素数の個数を数える • 効率的に数える方法として, エラトステネスの篩が有名 • 詳しくは先輩たちに聞く or ググる • 今回は, 複数の[l, r] のクエリに早く答える 方法を考えていこう.
高速化のアイディア 1 : 前計算 • エラトステネスの篩を用いれば勝手に 前計算がされている. ・試し割りをしている人は, 配列を用意して pが素数だったら 配列の p番目の 要素を 1 にしよう
高速化のアイディア2:累積和 • 刮目せよ!!! • さっき作った配列を…
高速化のアイディア2:累積和 • 刮目せよ!!! • さっき作った配列を…
高速化のアイディア2:累積和 • 刮目せよ!!! • さっき作った配列を… • 右に足していく
高速化のアイディア2:累積和 1 2 3 4 5 6 • この配列があると何が嬉しいか? • 考えてみよう!