分析
我们知道
$varphi * 1 = id$
$mu * 1 = e$
杜教筛即可
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<unordered_map>
using namespace std;
const int N = 5e6;
unordered_map<int,long long>phi;
unordered_map<int,int>mu;
unordered_map<int,bool>visp,vism;
long long _p[N+10];
int _m[N+10];
int cnt,p[N];
bool is[N+10];
inline long long get_phi(int x){
if(x<=N)return _p[x];
if(visp[x])return phi[x];
long long res=(long long)x*(x+1)/2;
int le=2,ri;
for(;le<=x;le=ri+1){
ri=x/(x/le);
res-=(ri-le+1)*get_phi(x/le);
}
visp[x]=1;return phi[x]=res;
}
inline int get_mu(int x){
if(x<=N)return _m[x];
if(vism[x])return mu[x];
int res=1,le=2,ri;
for(;le<=x;le=ri+1){
ri=x/(x/le);
res-=(ri-le+1)*get_mu(x/le);
}
vism[x]=1;return mu[x]=res;
}
inline void go(){
register int i,j,k;
_p[1]=_m[1]=1;
for(i=2;i<=N;++i){
if(!is[i])p[++cnt]=i,_m[i]=-1,_p[i]=i-1;
for(j=1;j<=cnt,i*p[j]<=N;++j){
is[p[j]*i]=1;
if(i%p[j]==0){
_m[i*p[j]]=0;
_p[i*p[j]]=_p[i]*p[j];
break;
}
_m[i*p[j]]=-_m[i];
_p[i*p[j]]=_p[i]*(p[j]-1);
}
}
for(i=2;i<=N;++i)_p[i]+=_p[i-1],_m[i]+=_m[i-1];
}
int main(){
int n,t;
scanf("%d",&t);
go();
while(t--){
scanf("%d",&n);
printf("%lld %d
",get_phi(n),get_mu(n));
}
return 0;
}