杜教筛模板题。
求欧拉函数和莫比乌斯函数的前缀和。
鼻炎犯了,证明改天写。。。。
(大佬们看看有没有错啊。。。为啥跑的这么慢。。。)
#include <iostream>
#include <cstdio>
#include <map>
using namespace std;
typedef long long ll;
const int N=7000000;
int n;
map<int,ll>ph,mu;
int prime[N>>3],tot;ll phi[N],miu[N];
bool vis[N];
void init() {
miu[1]=phi[1]=1;
for(int i=2;i<=N-5;i++) {
if(!vis[i]) prime[++tot]=i,miu[i]=-1,phi[i]=i-1;
for(int j=1;j<=tot&&prime[j]*i<=N-5;j++) {
vis[i*prime[j]]=1;
if(i%prime[j]==0) {phi[i*prime[j]]=phi[i]*prime[j];break;}
phi[i*prime[j]]=phi[i]*phi[prime[j]];miu[i*prime[j]]=-miu[i];
}
}
for(int i=1;i<=N-5;i++) phi[i]+=phi[i-1],miu[i]+=miu[i-1];
}
ll solvephi(int x) {
if(x<=N-5) return phi[x];
if(ph.count(x)) return ph[x];
ll ans=1ll*x*(x+1)/2;
for(int i=2,nxti;i<=x;i=nxti) {
nxti=x/(x/i)+1;
ans-=(nxti-i)*solvephi(x/i);
}
return ph[x]=ans;
}
ll solvemiu(int x) {
if(x<=N-5) return miu[x];
if(mu.count(x)) return mu[x];
ll ans=1;
for(int i=2,nxti;i<=x;i=nxti) {
nxti=x/(x/i)+1;
ans-=(nxti-i)*solvemiu(x/i);
}
return mu[x]=ans;
}
int T;
int main() {
init();
cin>>T;
while(T--){
cin>>n;
cout<<solvephi(n)<<' '<<solvemiu(n)<<endl;
}
}