luogu2568GCD题解--欧拉函数
Posted rye-catcher
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu2568GCD题解--欧拉函数相关的知识,希望对你有一定的参考价值。
题目链接
https://www.luogu.org/problemnew/show/P2568
分析
题目即求(sum_{i=1}^N sum_{j=1}^N [gcd(i,j)) (is) (a) (prime) (number) (])
我们提出这个素数变成(sum_p sum_{i=1}^{frac{N}{p} } sum_{j=1}^{frac{N}{p} } [gcd(i,j)) (is) (1])
对于后面两个(sigma),考虑(i>=j)和(i<j)两种情况,不难想到答案为(2 * (sum_{i=1}^{frac {N}{P} }phi(i))-1),因为(i=j=1)时多算了种情况
于是求欧拉函数表同时前缀和就好了
代码
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cctype>
#include <iostream>
#define ll long long
#define ri register int
using std::min;
using std::max;
template <class T>inline void read(T &x){
x=0;int ne=0;char c;
while(!isdigit(c=getchar()))ne=c==‘-‘;
x=c-48;
while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
x=ne?-x:x;return ;
}
const int inf=0x7fffffff;
int pri[1000005],tot=0;
ll phi[10000007];
int n;
inline void get_phi(){
bool vis[10000005];
memset(vis,0,sizeof(vis));
vis[1]=1,phi[1]=1;
for(ri i=2;i<=n;i++){
if(!vis[i]){pri[++tot]=i,phi[i]=i-1;}
for(ri j=1;j<=tot&&pri[j]*i<=n;j++){
vis[i*pri[j]]=1;
if(i%pri[j]==0){phi[i*pri[j]]=phi[i]*pri[j];break;}//定义式,i*pri[j]与i的质因数是相同的
else phi[i*pri[j]]=phi[i]*phi[pri[j]];//积性函数
}
}
for(ri i=2;i<=n;i++)phi[i]+=phi[i-1];
return ;
}
ll ans=0;
int main(){
read(n);
get_phi();
for(ri i=1;i<=tot&&pri[i]<=n;i++){
ans+=(phi[n/pri[i]]<<1)-1;
}
printf("%lld
",ans);
return 0;
}
以上是关于luogu2568GCD题解--欧拉函数的主要内容,如果未能解决你的问题,请参考以下文章