1. 程式人生 > >洛谷P2398 GCD SUM

洛谷P2398 GCD SUM

約數 std ron aps alt 100% print getc 技術

題目描述

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