因为(mu*I=epsilon)
所以设(h=mu*I,S_n=sum_{i=1}^nmu(i))
[sum_{i=1}^{n}h(i)]
[=sum_{i=1}^{n}sum_{d|i}mu(lfloorfrac{i}{d}
floor) imes I(d)
]
[=sum_{i=1}^nI(i)sum_{j=1}^{lfloor frac{n}{i}
floor}mu(j)
]
[=sum_{i=1}^nI(i) imes S(lfloorfrac{n}{i}
floor)
]
[=I(1) imes S(n)+sum_{i=2}^nI(i) imes S(lfloorfrac{n}{i}
floor)]
[I(1) imes S(n)=sum_{i=1}^{n}h(i)-sum_{i=2}^{n}S(lfloorfrac{n}{i}
floor)
]
[S(n)=1-sum_{i=2}^n{S(lfloorfrac{n}{i}
floor)}
]
[求sum_{i=1}^nphi(i)
]
因为(phi*I=id)
所以设(h=phi*I,S_n=sum_{i=1}^nphi_i)
[sum_{i=1}^nh(i)$$$$=sum_{i=1}^nsum_{d|i}phi(lfloorfrac{i}{d}
floor) imes I(d)$$$$=sum_{i=1}^nI(i) imes sum_{d|i}phi(lfloorfrac{i}{d}
floor)$$$$=sum_{i=1}^nI(i) imes sum_{t=1}^{lfloorfrac{n}{i}
floor}phi(t)$$]
=sum_{i=1}^nI(i) imes S(lfloorfrac{n}{i}
floor)$$$$
=I(1) imes S(n)+sum_{i=2}^n I(i) imes S(lfloorfrac{n}{i}
floor)
[]
S(n)=sum_{i=1}^nh(i)-sum_{i=2}^n I(i) imes S(lfloorfrac{n}{i} floor)
[]
S(n)=frac{(n+1) imes n}{2}-sum_{i=2}^n I(i) imes S(lfloorfrac{n}{i} floor)
[#### 注意事项
- 尽量减少常数
- 开头线性筛预处理的时候尽量开到$n^{frac{2}{3}}$或更大
- long long和int要区别
- 枚举2 TO N 可以整除分块
#### 代码
```cpp
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <unordered_map>
using namespace std;
const int MAXN = 5000000;
unordered_map<int,long long> Sumphi;
unordered_map<int,long long> Summu;
int iprime[MAXN+5],cnt;
long long mu[MAXN+5],phi[MAXN+5];
bool isprime[MAXN+5];
void prime(int n){
isprime[1]=true;
mu[1]=1;
phi[1]=1;
for(int i=2;i<=n;i++){
if(!isprime[i])
iprime[++cnt]=i,phi[i]=i-1,mu[i]=-1;
for(int j=1;j<=cnt&&iprime[j]*i<=n;j++){
isprime[iprime[j]*i]=true;
mu[iprime[j]*i]=-mu[i];
phi[iprime[j]*i]=phi[i]*(iprime[j]-1);
if(i%iprime[j]==0){
mu[iprime[j]*i]=0;
phi[iprime[j]*i]=phi[i]*(iprime[j]);
break;
}
}
}
for(int i=1;i<=n;i++){
mu[i]+=mu[i-1];
phi[i]+=phi[i-1];
}
}
long long djsmu(int n){//first mu second phi
if(n<=MAXN)
return mu[n];
if(Summu.count(n))
return Summu[n];
int mid1=0;
for(int i=2,j;i<=n;i=j+1){
j=min(n/(n/i),n);
mid1+=(j-i+1)*djsmu(n/i);
}
Summu[n]=1-mid1;
return Summu[n];
}
long long djsphi(int n){//first mu second phi
if(n<=MAXN)
return phi[n];
if(Sumphi.count(n))
return Sumphi[n];
long long mid1=0;
for(int i=2,j;i<=n;i=j+1){
j=min(n/(n/i),n);
mid1+=(j-i+1)*djsphi(n/i);
}
Sumphi[n]=1LL*(n+1)*n/2-mid1;
return Sumphi[n];
}
int main(){
prime(MAXN);
int T,n;
scanf("%d",&T);
for(int i=1;i<=T;i++){
scanf("%d",&n);
printf("%lld %d
",djsphi(n),djsmu(n));
}
return 0;
}
```]