1. 程式人生 > >luoguP2398 GCD SUM [gcd]

luoguP2398 GCD SUM [gcd]

100% sca 最大 turn src 利用 意思 pre nbsp

題目描述

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


題目的意思大概是這樣的

技術分享

O(n2)枚舉當然是不行的啦。

考慮枚舉k,求gcd為k的“數對”的個數。

而可以證明gcd為k的“數對”的個數為技術分享

利用容斥把gcd為2k,3k,4k的“數對”的個數減去就好啦?

註意k要從大到小枚舉。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 using namespace std;
 5 
 6 typedef long long ll;
 7 
 8 const int maxn=100005;
 9 
10 int n;
11 ll dp[maxn],ans=0;
12 
13 int main(){
14     scanf("
%d",&n); 15 for(int i=n;i>0;i--){ 16 dp[i]=1ll*(n/i)*(n/i); 17 for(int j=(i<<1);j<=n;j+=i) 18 dp[i]-=dp[j]; 19 ans+=dp[i]*i; 20 } 21 printf("%lld\n",ans); 22 return 0; 23 }

luoguP2398 GCD SUM [gcd]