@まとめ--13 @ふるいです


@ 0 - @参照

zsyリニアふるいブログ
唐先生の杜は、ふるいを教える(ORZ)
jiryの杜は、ふるいを教える(ORZ)
fjzzqの杜は、ふるいを教える(ORZ)
fjzzq'sMin_25ふるい(ORZ)
Min_25画面の拡張機能についてのブログ記事(ORZ)

@ 1--リニアふるいです@

実質的に線状のふるいクッションはさておき、ここで我々は唯一の任意の線形ふるい乗法関数値の使用を議論し(典型的には2つの関数の畳み込み積です)。

我々は、F(n)を選別したい場合は、n個のユニークな因数分解与えるために\を(P_1 ^ N = {P_2 A_1} * ^ * ... *} {A_2 P_K a_k ^ {} \) および\(P_1 <P_2 < ... <p_k \)
その後:\(F(N)= F(P_1 A_1 ^ {})* F(P_2 A_2 ^ {})* ... * F(P_Kのa_k ^ {})\)
線形画面は、我々は、nをスクリーニングする要因の最小数を渡します。我々はときに同時に画面取得した場合\(P_1 ^ {A_1} \ ) の値を、スクリーニングすることができる喜んF(N)。

まず第一に:我々は、(1)1 = Fを扱っています。
我々は、pは素数でふるいにかけたとき、私たちは、定義、F(P ^ 2)により、F(p)を取得し、 ... F(P ^ c)はcが最大値を満たすP ^ C≤MAXです。この後、多くの場合、F(P ^(K-1の前に利用さ )) (例えば、オイラー関数として)は、f(P ^ k)を与えます。
その後、我々はまた、(n)がローを処理するために対応するn表す(P_1 A_1を^ {} \)\をA1に基づく線形ふるい特定のプロセスは、1に等しいです。1に等しい場合、低い(n)はP1に等しく、そうでない場合は、低(N)=低い(N / P1)* P1。

この時間の複雑さは、まだ線形複雑度を制御するための時間です。

一次関数の画面例は、いずれかを必要とします。

杜@ふるいを教える - 2 @

もちろん上記は、私たちの研究の焦点では​​ありません。私たちは、導入された問題で見えるかもしれません。

与えられたn(nは10 ^ 11以下) 、 シーク(\ \ sum_ {I}を1 = N ^ {} \ファイ(I)\)
一見、私はそれが直鎖状鋳型タイトル画面だと思いました。結果よく見ると、10 ^ 11≤n個を発見しました。これ。全体の無知な人々がアップ強制することができます。
そのような問題は、呼び出された乗法関数プレフィックスと癌の捜査上の点の数、問題、およびこれらの問題は、近年であることが多いです。
今回のように、我々はデュふるい(ORZのDYH)を教えるために使用することができます。

私たちは知っている(\ファイ\)\非常に古典ディリクレ畳み込み式を有する:\(\ファイI *上記は= \ ID言及した)を
そして、私たちは、知っている\(上記ID \)プレフィックスをし、良いを求めています。
だから我々はしようとした(\ファイ\)を\に変わり\(IDの\)私たちの速度を改善、解決するために:
\ [\ sum_ {I = 1} ^ {N-} ID(I)= \ sum_ {I = 1。} ^ {N-} \ sum_ {D | I} \ピー(\ FRAC {I} {D})* I(D)\]
\ [\ FRAC {N- *(N - 1)} {2} = \ sum_ { A * B \ルN} \ PHI(A)= \ sum_ {B = 1} ^ {N} \ sum_ {i = 1} ^ {\ lfloorの\のFRAC {n}が{B} \ rfloor} \ PHI(I )\]

覚えるかもしれない(S(N)= \ sum_ {I} 1 = N ^ {} \ファイ(I)\)\を:、その後、上記式はさらに変換することができる
\ [S(N)= \ {N-FRAC×(N- 1)} {2} - \ sum_ {i = 2} ^ {n}はS(\ lfloorの\のFRAC {N} {I} \ rfloor)\]

これは、S(n)と他のSとの間の関係を確立します
メモリ検索を使用する場合の使用(\ \ lfloorの\のFRAC {N } {I} \ rfloor \) のみ\(2 * \ SQRT {N } \) 種を含む\に(\のSQRT {N} \)\(\ル\} N-SQRT {\)

我々は、時間の複雑さを分析する、T(n)がS(n)の時間を解決する複雑さを表してみましょう。メモリ検索有するので、それは:
\ [T(N)= \ sum_ {I = 1} ^ {\のSQRT {N-}}(\のSQRT {I} + \のSQRT {\ FRAC {N-} {I }})\]

与えるために、それに合うように一体\を(T(N)= O(N ^ {\ FRAC。4} {} {}。3)\)
前処理は、最初の正の整数S、およびK場合\(GE \ \ K N-SQRTを{} \)を得ることができる:
[T(N)= \ sum_ 1 {I} = {^ \ N-FRAC {} \ {K}} \ SQRT {\ FRAC {n}は{I} = O(\ FRAC {N}は{\ SQRT {K}})\]

場合\((K = OをN ^ {\ FRAC {2} {3}})\) がある場合\(O(K)= O(\ FRAC {N-} {\のSQRT {K})\)、最適なバランスにこの複雑で。

私たちは数論的関数が必要な場合、一般的には、\(F(N)を\) 注:これは唯一の乗法機能に簡単前処理するので、必ずしも乗法関数ではありません)とプレフィックス\(S(N)\) 我々はコンストラクタ試すことができます\(G(N)\)\(N)\ H()ように\(F * G = H \)および\(H \)プレフィックスをし、良いを見つけます。
次いで、上記プレフィックスとオイラー関数に従って、以下の結果を導き出すことができる:
\ [G * S(N)= \ sum_ 1 = {I}} ^ {N-H(I) - \ sum_ {I = 2(1)。 } ^ {n}はG(I )* S(\ lfloorの\のFRAC {N} {I} \ rfloor)\]

Sの前処理\(O(N ^ {\ FRAC {2} {3}})\) DUはふるいを教える実装するキー。
もちろん、あなたが私に尋ねる\(グラム\)をどのように構築。emmm私はあなたがあなた自身の感じを構築することができ、これを言うことはありません。
(ので\(グラム\)構造がしばしば困難がああフィードあり)

例。
参照コード:

#include<cstdio>
#include<cstring>
typedef long long ll;
const int MAXN = 5000000;
const int MOD = 1000000007;
ll sphi[MAXN + 5]; int phi[MAXN + 5];
int prm[MAXN + 5], pcnt = 0;
bool is_prm[MAXN + 5];
void sieve() {
    phi[1] = sphi[1] = 1;
    for(int i=2;i<=MAXN;i++) {
        if( !is_prm[i] ) {
            prm[++pcnt] = i;
            phi[i] = i-1;
        }
        for(int j=1;i*prm[j]<=MAXN;j++) {
            is_prm[i*prm[j]] = true;
            if( i % prm[j] == 0 ) {
                phi[i*prm[j]] = phi[i]*prm[j];
                break;
            }
            else phi[i*prm[j]] = phi[i]*phi[prm[j]];
        }
        sphi[i] = (sphi[i-1] + phi[i])%MOD;
    }
}
bool tag_phi[MAXN + 5]; ll dp_phi[MAXN + 5];
ll solve_phi(ll n, int k) {
    if( n <= MAXN ) return sphi[n];
    if( tag_phi[k] ) return dp_phi[k];
    ll ret = (n%MOD)*((n+1)%MOD)%MOD*500000004%MOD; ll l = 2;
    while( l <= n ) {
        ll r = n/(n/l);
        ret = ret - solve_phi(n/l, k*l)*(r-l+1)%MOD;
        l = r + 1;
    }
    tag_phi[k] = true;
    return dp_phi[k] = ret;
}
int main() {
    sieve(); ll N;
    scanf("%lld", &N);
    printf("%lld\n", (solve_phi(N, 1)%MOD + MOD)%MOD);
}

3 @ - 分 - 25画面@

(PS:現在のブロガーだけで、基本的な分-25の操作、より高度な拡張しません...)

ドゥは、画面を教える自体が構築される機能の性質に依存しすぎています。
任意の乗法関数f(n)が与えられた場合、我々は、どのようにFの接頭辞を尋ねるとすべきか?

呼び出さアイランドハウス画面を実現することができた\(O(\ FRAC {N ^ {\ FRAC {3} {4}}} {\ログN})\) の複雑さを。
そして、画面上の爆発的なステップの分-25形而上学の複雑さは、時代の涙になります。
実際、ZZT dalaoは、証明(N \の当量10 ^ {\ \ 13}) アイランドハウス画面データが通る内、最小-25は、篩を通して実行できます。

最適化アルゴリズムの考え方は、次のとおりの共存の総数\(\ル\ SQRT {N } \) 素因数。
しかし、このアルゴリズムは、効果的な場合は、その提供:
(1)は、f(p型)を(これはAを必要とする理由を知っている分を待つ)多項式です。
(2)ここで、f(P ^ kが ) 容易に(K> 1)を算出することができます。

まず、私たちは、それをnと乗法関数よりも小さい素数を表すG(N)に対処する必要があります。G(n)を得るためには、我々ができ徐々に再帰H(I、N-):
\ [H(I、N-)= \ sum_ {|| K Kは、品質の最小素因数>プライム[I]である} ^ { 1 <K \ルn}はF( K)\]

注:この、次のF(k)は、その真の価値乗法関数ではありませんが、F(P)による多項式を計算しました。
実装された場合、それがfされなければならない(K)は、2つの特性乗法関数と多項式を満たすために、それぞれ式の個々の和の数に分割されます。

エリクセン画面は、実際には、法律のプロセスです。時間、二つのカテゴリーに移し:
場合(1) プライム[I] ^ 2 \ \ルN \) :
\ [H(I、N-)= H(I-1、N-) - F(素数を[ I])*(H(I -1、\ lfloor FRAC {N} {プライム[I]} \ rfloor \) - \ sum_ {k = 1} ^ {I-1} F(プライム[K]))\ ]

Hので(I、N)は、2つの部分からなる:素数、最小の品質係数の\(>プライム[I] \ ) 、それが素数の場合を減算することです。
この操作により、我々は取り除くことができます\(プライム[i]が\)数の倍数が選別されていないです。

(2)当\(プライム[I] ^ 2> N \)时:
\ [H(I、N)= hの(I-1、N)\]

これは明らかです。エジプトのスクリーニング方法によれば、このような状況は、任意の数を取り除くことはありません。
これは(2)の場合は、直接圧延のアレイを展開することができるセクションに見出すことができます。

セット\(\ル\ SQRT {N } \) 素数の数はPCNT、最終ある\(H(PCNT、nは) \) である\(G(N)\)
と同時に、同じルーチン、\( \ lfloorの\のFRAC {N} {プライム[I]} \ rfloor \) のみ\(O(\ SQRT {N })\) の可能な値。
このプロセスの複雑?ある\(O(\ FRAC {N ^ {\ FRAC {3} {4}}} {\ログN})\) 。証明?私はあまりにも料理ができませんごめんなさい。

質問は今、どのように我々は、前処理します\(H(0、N-を)\)
それは非常に特殊であり、私たちだけのため\(H(0、N-)= \ sum_ {I} = ^ {N-2} F(I)\)(1)、最後に最後の特別な処理F。
あなたは今見つけることができます:あなたはfが多項式であると言うなら、私たちは喜んでパワーと自然数を振ることができます。

わかりました。私たちは今扱われている\(G(n)は\)のnとの和乗法関数よりも小さい素数を表します。
今我々が対処しなければならない\(Sを(I、N-)\) 同様に、として定義される
\ [S(I、N-)= \ sum_ {J最低品質係数\ GEプライム[I]} ^ {1 <J \ルn}はF(J) \]

(注:Fは、その実際の値が乗法関数です)

品質第一処理部の数、すなわち:
\ [A = G(N、PCNT) - 。\ sum_ {J} 1 ^ = {I} 1-F(プライム[J])\]

これは理解しやすいです。

次に、係合部の数は、品質係数の最小数及びパワーを列挙するために私達に従事:
\ [B = \ sum_ {J} = ^ {プライムI [J] ^ 2 \ I}ルの\ sum_ 1} = {E ^ {プライム[J] ^ {E + 1} \ルI}(F(プライム[J] ^ E)* S(\ lfloorの\のFRAC {N} {プライム[J] ^ E} \ rfloor、J + 1) + F(プライム[J] ^ {E + 1}))\]

接合の数も2つに分割されているので、実際には、少し長くなります一つは、他の素因数の2つ以上を含む、フォームP ^ K(K> 1)のタイプのものです。
私たちなので、F(1)特殊な計算であるので、この分類が必要です。

最終的に得\(S(I、N-)= A + B \) 結合の数を計算の複雑さはO(形而上)です。

例。
F(2)= 3、Fの他に見出すことができる 1( - (P)= P の両方奇数)。
だから、Fについてのみ、最後の特別な処理を必要とする(2)。
参照コード:

#include<cstdio>
#include<cmath>
typedef long long ll;
const int MOD = int(1E9) + 7;
const int SQRT = int(1E5);
const int INV2 = (MOD + 1)>>1;
inline int add(ll x, ll y) {return (x%MOD + y%MOD)%MOD;}
inline int sub(ll x, ll y) {return add(x%MOD, MOD - y%MOD);}
inline int mul(ll x, ll y) {return (x%MOD)*(y%MOD)%MOD;}
ll n, sq;
int prm[SQRT + 5], pcnt;
bool nprm[SQRT + 5];
void sieve() {
    for(int i=2;i<=SQRT;i++) {
        if( !nprm[i] ) prm[++pcnt] = i;
        for(int j=1;i*prm[j]<=SQRT;j++) {
            nprm[i*prm[j]] = true;
            if( i % prm[j] == 0 ) break;
        }
    }
}
ll arr[2*SQRT + 5]; int num1[SQRT + 5], num2[SQRT + 5], cnt;
inline int id(ll x) {return x > sq ? num1[n/x] : num2[x];}
int g[2*SQRT + 5], h[2*SQRT + 5], G[2*SQRT + 5];
void getG() {
    for(ll x=1;x<=n;x=n/(n/x)+1) {
        arr[++cnt] = n/x;
        (n/x > sq ? num1[n/(n/x)] : num2[n/x]) = cnt;
    }
    for(int i=1;i<=cnt;i++) {
        g[i] = sub(mul(add(mul(arr[i], arr[i]), arr[i]), INV2), 1);
        h[i] = sub(arr[i], 1);
    }
    for(int i=1;i<=pcnt;i++)
        for(int j=1;j<=cnt&&prm[i]<=arr[j]/prm[i];j++) {
            g[j] = sub(g[j], mul(prm[i], sub(g[id(arr[j]/prm[i])], g[id(prm[i-1])])));
            h[j] = sub(h[j], sub(h[id(arr[j]/prm[i])], h[id(prm[i-1])]));
        }
    for(int i=1;i<=cnt;i++) {
        G[i] = sub(g[i], h[i]);
        if( arr[i] >= 2 ) G[i] = add(G[i], 2);
    }
}
int min_25(int n, int k) {
    if( arr[n] < prm[k] ) return 0;
    int ret = sub(G[n], G[id(prm[k-1])]);
    for(int i=k;i<=pcnt&&prm[i]<=arr[n]/prm[i];i++)
        for(ll c=1,j=prm[i];j<=arr[n]/prm[i];c++,j*=prm[i])
            ret = add(ret, add(mul(prm[i]^c, min_25(id(arr[n]/j), i+1)), prm[i]^(c+1)));
    return ret;
}
int main() {
    scanf("%lld", &n), sq = sqrt(n);
    sieve(), getG();
    printf("%d\n", min_25(1, 1) + 1);
}

@ 4 - 強力な数(咕)@

WC2019を導入しました。

基本的には、クッションの上に、ではないでしょう。

おすすめ

転載: www.cnblogs.com/Tiw-Air-OAO/p/11604767.html