裸的杜教筛。
注意long long。。。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> #define maxn 5000050 using namespace std; long long n,prime[maxn],tot=0,phi[maxn]; bool vis[maxn]; map <long long,long long> mp; void get_table() { phi[1]=1; for (long long i=2;i<=maxn-50;i++) { if (!vis[i]) {prime[++tot]=i;phi[i]=i-1;} for (long long j=1;j<=tot && i*prime[j]<=maxn-50;j++) { vis[i*prime[j]]=true; if (i%prime[j]) {phi[i*prime[j]]=phi[i]*(prime[j]-1);continue;} else {phi[i*prime[j]]=phi[i]*prime[j];break;} } } for (long long i=1;i<=maxn-50;i++) phi[i]+=phi[i-1]; } long long get_phi(long long x) { if (x<=maxn-50) return phi[x]; if (mp[x]) return mp[x]; long long ans=(long long)x*(x+1)/2; long long l=2,r; while (l<=x) { r=x/(x/l); ans-=(long long)(r-l+1)*get_phi(x/l); l=r+1; } return mp[x]=ans; } int main() { scanf("%lld",&n);get_table(); printf("%lld\n",get_phi(n)); return 0; }