羅区[P2568] GCD

タイトル

リンクタイトル:https://www.luogu.com.cn/problem/P2568
指定された整数\(N \) シーク\(1 \当量X、Y \ N当量\) と\(GCD(X、Y) \)に素数の数である\((X、Y)\ ) どのように多くのペア。

思考

列挙子素数を考える(P \)\、各素数のための\(P \)、\ ([1、N - ] \でX、Y \)\(\ GCD(X、Y )= P \) のプログラム番号は([IN X、Y \ \ 1、\左\ lfloor \ FRAC {N} {P} \ \右rfloor] \) と\(\ GCD(X、Y )= 1 \) 番号スキーム。
考慮\(1 \当量X \当量 Y \当量のn \) と\(\ GCD(X、Y )= 1 \) 番号スキームを\(\和^ {\左 \ lfloor \ FRAC {n}は{ P} \右\ rfloor} _ {私は= 1} \ varphi(I)\) およびNOがない場合\(x \当量Y \)この制限は、プログラムナンバーである(2 \和は^ {\ \ \ lfloorを左\ {} {P N-FRAC} \右\ rfloor 1}} _ {I = \ varphi(I) - [IがJに= \ GCD(I、J)= 1。] \)明らかに後者のみ\(I = J = \ 1 ) 場合、\(1 \当量X、Y \当量のn \) と\(\ GCD(X、Y )= P \) プログラムの数であります\(2 \ ^ {rfloor \右\ SUM \左\ lfloor \ {N-FRAC {P} 1}} _ {I = \ varphi(I)\)
遮蔽\(1 \シムnは\)方法シークをプライミング\(\ varphi \) 次いで(\ \ varphi \)は、接頭辞と、各素数のためにその\(P \)であることができる\(O(1 )\)の回答を求めています。
最終的な答えは
[\ sum_ {P \で\ operatorname \ {プライム}}((2 \ sum_ {i = 1} ^ {\左\ lfloor \ FRAC {N} {P} \ rfloor \右} \ varphi [I ]) - 1)\]
時間計算\(O(N)\)

コード

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;

const int N=10000010;
int n,m,v[N],prime[N],phi[N];
ll ans,sum[N];

void find_prime(int n)
{
    phi[1]=1;
    for (int i=2;i<=n;i++)
    {
        if (!v[i]) v[i]=i,prime[++m]=i,phi[i]=i-1;
        for (int j=1;j<=m;j++)
        {
            if (prime[j]>v[i] || 1LL*prime[j]*i>n) break;
            v[i*prime[j]]=prime[j];
            if (i%prime[j]) phi[i*prime[j]]=phi[i]*(prime[j]-1);
                else phi[i*prime[j]]=phi[i]*prime[j];
        }
    }
    for (int i=1;i<=n;i++)
        sum[i]=sum[i-1]+phi[i];
}

int main()
{
    scanf("%d",&n);
    find_prime(n);
    for (int i=1;i<=m;i++)
        ans+=2*sum[n/prime[i]]-1;
    printf("%lld",ans);
    return 0;
}

おすすめ

転載: www.cnblogs.com/stoorz/p/12305929.html