D题
先补一道简单的题,观察规律发现结果是小于等于所给数字n的每一项欧拉和。
方法一:
#include<iostream>
#define Max 1000010
using namespace std;
int phi[Max];
void getphi() {
phi[1] = 1;
for(int i = 1; i < Max; i++)
phi[i] = i;
for(int i = 2; i < Max; i++)
if(phi[i] == i)//如果i是质数
for(int j = i; j < Max; j += i)
phi[j] = (phi[j] / i) * (i-1);
}//欧拉打表
int main(){
getphi();
int x;
while(1){
int x;
long long cnt = 0;
cin >> x;
if(x == 0)
break;
else{
for(int i = 2; i <= x; i++)
cnt += phi[i];
}
cout << cnt << endl;
}
return 0;
}
依次求欧拉数,最后累加
方法二:
#include <stdio.h>
#include <iostream>
using namespace std;
int oula[1000010];
int main()
{
int n;
for(int i=1;i<1000010;i++)
{
oula[i]=i;
}
for(int i=2;i<1000010;i++)
{
if(oula[i]==i)
{
for(int j=i;j<1000010;j+=i)
{
oula[j]=(oula[j]/i)*(i-1);
}
}
}
while(cin >> n&&n)
{
long long ans=0;
for(int i=2;i<=n;i++)
{
ans+=oula[i];
}
cout << ans << endl;
}
}
B题
//F[N]=∑gcd(i, N) 得 F(N)=∑pi*φ(N/pi)
//φ(N/pi)就是1~N中所有满足gcd(s,N)=pi的s的个数
#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
int getphi(int n) {
int rea = n;
for(int i=2; i*i<n; i++) {
if(n%i == 0) {
rea = rea - rea/i;
do{
n /= i;
}while(n%i == 0);
}
}
if(n > 1) {
rea = rea - rea/n;
}
return rea;
}
int main() {
int n;
ll ans;
while(scanf("%d",&n)!=EOF) {
ans = 0;
for(int i=1; i*i<=n;i++) {
if(n%i == 0) {
ans += i*getphi(n/i);
if(i*i!=n) //避免重复相加 eg.当n=9,3*getphi(3)会出现两次
ans += (n/i)*getphi(i);
}
}
cout << ans <<endl;
}
return 0;
}
C题 题意很简单,可与B题做对比
#include<iostream>
#define ll long long
using namespace std;
int getphi(int n) {
int rea = n;
for(int i=2; i*i<=n; i++) {
if(n%i == 0) {
rea = rea - rea/i;
do{
n /= i;
}while(n%i == 0);
}
}
if(n>1)
rea = rea-rea/n;
return rea;
}
int main() {
int T;
cin >> T;
while(T--) {
int n,m;
ll cnt=0;
cin >> n >> m;
for(int i =1; i*i<=n; i++) {
if(n%i == 0) {
if(i >= m)
cnt += getphi(n/i); //注意跟B题区分,这里是统计个数所以不用乘i
if(i*i!=n && n/i>=m)
cnt += getphi(i);
}
}
cout << cnt << endl;
}
return 0;
}
F题 可以参见小陈同学的博客https://blog.csdn.net/qq_44587145/article/details/96131006,解释的十分详细,赞一个~,注意和要B题进行对比
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 4e6+ 7;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
typedef pair<int, int> pis;
int phi[maxn];
void getPhi() {
for (int i = 1; i < maxn; i ++)
phi[i] = i;
for (int i = 2; i < maxn; i ++)
if(phi[i] == i)
for (int j = i; j < maxn; j += i)
phi[j] = (phi[j]/i) * (i-1);
}
ll getS(int x) {
return 1ll * (x + 1) * x / 2;
}
int main() {
getPhi();
int n;
while(cin >> n && n) {
ll ans = 0;
for (int i = 2; i <= n; i ++) {
ans += getS(n/i) * phi[i];
}
cout << ans << endl;
}
return 0;
}