GCD 题解
__S08577__ · · 题解
B
题意
给定正整数
思路
脑抽数论题。
形象化题意:
不难发现,
于是可以将式子转化成
不难发现,这个式子具有对称性,即很多计算重复了两次,我们可以简化一下式子:
-1 是因为
而这个式子
式子又可以转化为:
最后要求的式子便为:
其中,欧拉函数可以利用前缀和优化思想
而质数可以用欧拉筛线性求出。
(不会欧拉筛的请看这里,欧拉函数的请看这里这里)
代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<stack>
#include<map>
#include<queue>
using namespace std;
#define int long long
#define ll long long
#define Endl cout<<endl;
#define xy cout<<"xy";
#define yx cout<<"yx";
#define pii pair<int,int>
#define ls(rt) tr[rt].ch[0]
#define rs(rt) tr[rt].ch[1]
const int N=1e7+10;//注意修改
const int mod=1e9+7;
const int M=2e5+10;
int prime[N],st[N],n,cnt=0,phi[N],s[N],ans;
void Pr(){
phi[1]=1;
for(int i=2;i<=n;i++){
if(st[i]==0){
cnt++;
prime[cnt]=i;
phi[i]=i-1;
}
for(int j=1;j<=cnt&&prime[j]*i<=n;j++){
st[prime[j]*i]=1;
if(i%prime[j]==0) {
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
else phi[i*prime[j]]=phi[i]*phi[prime[j]];
}
}
}
signed main(){
cin>>n;
Pr();
for(int i=1;i<=n;i++) s[i]=s[i-1]+phi[i];
for(int i=1;i<=cnt;i++) ans+=2*s[n/prime[i]]-1;
cout<<ans;
return 0;
}
/*
*/