洛谷P2398 GCD SUM

Posted 友人A

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷P2398 GCD SUM相关的知识,希望对你有一定的参考价值。

题目描述

for i=1 to n

for j=1 to n

 sum+=gcd(i,j)

给出n求sum. gcd(x,y)表示x,y的最大公约数.

输入输出格式

输入格式:

 

n

 

输出格式:

 

sum

 

输入输出样例

输入样例#1:
2
输出样例#1:
5

说明

数据范围 30% n<=3000 60% 7000<=n<=7100 100% n<=100000

——————————————————————————————————

又是数论QAQ

我们可以枚举k

ans=∑k*f[k]

f[k]表示gcd(i,j)=k的个数

f[k]=(n/k)(n/k);

但是我们还要扣掉前面gcd=2k,3k,4k........的

所以f[k]=[n/k]^2-(f[2k]+f[3k]+....)

复杂度是n*(1+1/2+1/3+...+1/n)

根据定积分公式$\int_0^n 1/x{\rm d}x $=ln(n)-ln(1)=ln(n)

所以总复杂的为nln(n)

技术分享
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int M=100007;
LL read(){
    LL ans=0,f=1,c=getchar();
    while(c<0||c>9){if(c==-) f=-1; c=getchar();}
    while(c>=0&&c<=9){ans=ans*10+(c-0); c=getchar();}
    return ans*f;
}
LL n,f[M],ans;
int main()
{
    n=read();
    for(int i=n;i>=1;i--){
        f[i]=(n/i)*(n/i);
        for(int j=i*2;j<=n;j+=i) f[i]-=f[j];
        ans+=i*f[i];
    }printf("%lld\n",ans);
    return 0;
}
View Code

 



以上是关于洛谷P2398 GCD SUM的主要内容,如果未能解决你的问题,请参考以下文章

洛谷题解P2303 [SDOi2012]Longge的问题

洛谷P3455- [POI2007]ZAP-Queries - 莫比乌斯反演

[洛谷1390]公约数的和

洛谷P1447 - [NOI2010]能量采集

洛谷P2522 - [HAOI2011]Problem b

洛谷P2522- [HAOI2011]Problem b - 莫比乌斯反演+杜教筛+数论分块