思路:




:回归梦想



#include<bits stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int prime[maxn], vis[maxn],phi[maxn];
void initial(const int n=1e5) {
    int cnt=0; phi[1]=1;
    for(int i=2;i<=n;i++) {
        if(vis[i]==0) { prime[++cnt]=i; phi[i]=i-1;vis[i]=i; }
        for(int j=1;j<=cnt;j++) {
            if(prime[j]>vis[i]||i*prime[j]>n) break;
            vis[i*prime[j]]=prime[j];
            if(i%prime[j]==0) {
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
            else phi[i*prime[j]]=phi[i]*(prime[j]-1);
        }
    }
    for(int i=1;i<=n;i++) phi[i]+=phi[i-1];
}
int main() {
    initial();
    int n; scanf("%d",&n);
    printf("%lld\n",2ll*phi[n-1]+1);
    return 0;
}

#include <bits stdc++.h>
using namespace std;
const int maxn = 5e4+10;
int n, phi[maxn];
void get_phi(int n) {
    phi[1] = 1;
    for(int i = 2; i <= n; i++) if(!phi[i]) {
        for(int j = i; j <= n; j += i) {
            if(!phi[j]) phi[j] = j;
            phi[j] = phi[j] / i * (i-1);
        }
    }
}
int main() {
    scanf("%d", &n);
    get_phi(n);
    int ans = 0;
    for(int i = 1; i < n; i++) ans += phi[i];
    printf("%d", ans * 2 + 1);
    return 0;
}

#include <bits stdc++.h>
using namespace std;
const int maxn = 5e4+10;
int n, phi[maxn];
long long Euler( long long n ){
       long long res = n;
     for( long long i =2 ;i*i<=n;i++){
         if( n %i == 0 ){
            n/=i;
            res = res - res/i;
        }
         while( n % i==0)
         n/=i;
     }
     if( n > 1 )
         res = res - res/n;
     return res;
}

int main() {
    scanf("%d", &n);
    int ans = 0;
    for(int i = 1; i < n; i++) ans += Euler(i);
    printf("%d", ans * 2 + 1);
    return 0;
}

也可以先筛出素数再用公式法:

vector<int>prime;
bool vis[maxm];
void initial() {
    for (int i = 2; i < maxm ; ++i) {
        if (!vis[i]) prime.emplace_back(i);
        for (int j = 0,size=prime.size(); j < size; ++j) {
            if (i * prime[j] >= maxm) break;
            vis[i * prime[j]] = true;
            if (i % prime[j] == 0) break;
        }
    }
}
inline ll Phi(ll p){
    ll x=p;
    for(int i:prime) {
        if(i>x) break;
        if(x%i==0){
            while(x%i==0)x/=i;
            p=p/i*(i-1);
        }
    }
    if(x>1)p=p/x*(x-1);
    return p;
}