\(更新\ \ \ 2018年11月18日\ ) 変更\(LETEX \) 、その他は変更されていません
中級I \(AFO \) 、および赤名からブルー名の成功に落ちました
\(更新2019年7月22日\)プラス感情自分の学校の文化レッスンの多く
そこ私は数論を聞いたと言っている\(GCDは\)ので、私はこの質問を開いたが、この問題はそれほど単純ではないことがわかりました
だから私はこの問題に対する解決策を記述します(本当に多くのナンセンス)
オイラー機能:事を紹介
定義:正の整数(\ \ N-) 、より等しいかそれ以下\(\ N-) 、及びと(\ N-)\正の整数の数(1を含む)が互いに素と呼ば(φ(N)\)\。(\(Φ(1)。1 = \) )
数式が書かれている(φ(N)= \ \ displaystyle \ sum_ {i = 1} ^ N1(GCD(I、N)= 1)\)
だから、答えは何ですか?
私たちは、それぞれの素数を検討\(のp \)すべての素数のための答えへの貢献、\(p個の\を)
\(GCD(X、Y) = 1 \)は、 と等価である\(GCD(* pを、 b *表P)= P \)
そう\(GCD(X、Y) \) の\(P \)数が数である\(1 <= B <= \ FRAC {N} {P} \) と互いに素である(\ A、B \)になるかもしれない番号、\を(<= B \)
それぞれについて\(B \)している(φ(B)\)\番目の引数が作る\(、B \)プライム、および\(GCD(* pを、 b *のpを)= P \)
したがって、この質問に対する答えは\(\ displaystyle \ sum_ {I = 1} ^ nはφ(I)\)
一部で開始します\(φ(n)は\)文字:
乗法機能(と共通)
$ε(N)= [N == 1] D(N)= \ displaystyle \ sum_ {D | n}は1つのσ(N)= \ displaystyle \ sum_ {D | N}のD $
$μ(N)= [MAX(C_1、C_2、... c_m)<= 1] *( - 1)^ m個の$
もちろん、そこに\(φ(n)は\)私自身は、
関数の製品の特性:もし\(GCD(A、B) == 1 \) 次に\(F(\倍B F)= F(A)\回(B)\)
\(φ(N)\)他の特性
1.場合\(P \)が素数である(φ(P)= P \ -1 \)
2.もし\(P | N \)と\(P ^ 2 | N- \) 、次いで\(φ(N)=のφ (N / P)\倍のp \)
3.場合\(P | N \)が、満足していない\(P ^ 2 | N-を\) 、次いで(φ(N)=φの\ \倍(P-1)\(N / P))
4. \(\ displaystyle \ sum_ {D | N}φ(D)= N \)
だから今の問題はすぐに追求するように変換する方法です\(φ(n)を\)
オイラーふるいは、関連することができるとしてもよい(O(N)\)\すべての時間内に決定素数。
用した場合\(Iは\)それは全て既知である場合、\(1-iは\)\(Φ\) 、列挙\(<= iは\)素数\(P [J] \)、決定することができます\(φ(X \回P [J])\)
1.もし\(P [J] \)と\(X \)プライム\(φ(X * P [ J])=φ(X)*φ(P [J])\)
2.そうでない場合には、プライム、提供\(X = Tの*はP [ J] ^ k個の\)
\(Z(X * Pの[J]) = Z(T * pを[J] ^ {K + 1})= Z(T)* F(P [J] ^ {K + 1})\)\( = F(T)* F(P [J] ^ K) * P [j]が= F(X)* P [j]を \)
そのため、前処理\(φ(I)\)コード:
for (int i=2;i<=n;++i){
if (is_prime[i]) phi[i]=i-1,prime[++prime_num]=i;
for (int j=1;j<=prime_num&&prime[j]*i<=n;++j){
is_prime[prime[j]*i]=0;
if (__gcd(prime[j],i)==1) phi[prime[j]*i]=phi[prime[j]]*phi[i];
else phi[prime[j]*i]=prime[j]*phi[i];
if (i%prime[j]==0) break;
}
}
プレフィックスとはそれに何かをします
最後に、警告の言葉は、\(10 \)で\(OI \)仕事を得る、開けないでください(\長い\ロング)\を祖先を参照してください。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=10000005;
bool is_prime[N];
int n,prime_num,prime[N],phi[N];
long long sum[N];
int main(){
scanf("%d",&n);
memset(is_prime,1,sizeof(is_prime));
is_prime[1]=0;phi[1]=1;
for (int i=2;i<=n;++i){
if (is_prime[i]) phi[i]=i-1,prime[++prime_num]=i;
for (int j=1;j<=prime_num&&prime[j]*i<=n;++j){
is_prime[prime[j]*i]=0;
if (__gcd(prime[j],i)==1) phi[prime[j]*i]=phi[prime[j]]*phi[i];
else phi[prime[j]*i]=prime[j]*phi[i];
if (i%prime[j]==0) break;
}
}
for (int i=1;i<=n;++i) sum[i]=sum[i-1]+phi[i];
long long ans=0;
for (int i=1;i<=prime_num&&prime[i]<=n;++i)
ans+=(sum[n/prime[i]]<<1)-1;
printf("%lld\n",ans);
return 0;
}