一,题目
Description
给你一个整数N,问你在[1,N]中的每个数字i
其与N来求最大公约数的结果的累加和
Format
Input
第一行输入一个正整数N
1<=N<=2^32
Output
输出1行
Samples
输入数据 1
6
输出数据 1
15
Hint
gcd(1,6)=1
gcd(2,6)=2
gcd(3,6)=3
gcd(4,6)=2
gcd(5,6)=1
gcd(6,6)=6
以上结果加起来正好为15
二,60分做法
直接照着题意模拟,用一个变量s记录答案,枚举1~n的数并将s+=__gcd(i,n),最后输出即可。
时间复杂度为O(n log(n))
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,s,t;
signed main()
{
cin>>t;
s = 0;
for(int i = 1;i <= t;i++) s += __gcd(i,t);
cout<<s<<endl;
return0;
}
三,100分做法
拿样例举例:
6 = 1 * 6,那么fin(1) = 1,1 * (6 / 1) = 6
6 = 2 * 3,那么fin(2) = 1,1 * (6 / 2) = 3
6 = 3 * 2,那么fin(3) = 2,2 * (6 / 3) = 4
6 = 6 * 1,那么fin(6) = 2,2 * (6 / 6) = 2
那么我们就只需要把6 + 3 + 4 + 2 = 15即是答案!
也就是用ans存储答案,再枚举n的因数i,将ans += fin(i) * (n / i);然后因为枚举一个因数就能得到另一个因数n / i,所以先判断i * i 是否等于n,不是的话再将n / i 替换i,也就是将ans += fin(n / i) * (n / (n / i));最后输出ans即可。
p.s:
1.此处fin()为欧拉函数,设N=a^a1* b^b1* c^c1* ....则fin(N)代表比N小且与N互质的数的个数,也就是N*(1-1/a)(1-1/b)(1-/c)....
2.在这里要特判fin(1) = 1!
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,s,t,ans;
int fin(int n)
{
if(n == 1) return 1;
int t;
double p,s;
queue<int>q;
s = n;
for(long long i = 2; i <= s / i; i++)
{
if(n % i == 0)
{
q.push(i);
while(n % i == 0) n /= i;
}
}
if(n > 1) q.push(n);
while(!q.empty())
{
t = q.front();
q.pop();
p = 1.0 - 1.0 / t;
s *= p;
}
return s;
}
signed main()
{
cin>>n;
int t = n;
for(int i = 1;i <= n / i;i++)
if(n % i == 0)
{
int f = fin(i);
t = f * (n / i);
ans += t;
if(i * i == n) continue;
f = fin(n / i);
t = f * (n / (n / i));
ans += t;
}
cout<<ans;
return 0;
}
最后,如果看懂的话,就请给我点个赞吧!qwq