orz我还以为要卡很久的常数。。。2333 10s给我过了。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 1000050
#define mod 999983
using namespace std;
int t,n,tot=0,miu[maxn*5],prime[maxn*5],tot1=0,g1[maxn],g2[maxn],tot2=0;
bool vis[maxn*5];
long long phi[maxn*5];
{
int nxt,id;
long long val;
}l1[maxn],l2[maxn];
void get_table()
{
miu[1]=1;phi[1]=1;
for (int i=2;i<=5000000;i++)
{
if (!vis[i])
{
phi[i]=i-1;miu[i]=-1;
prime[++tot]=i;
}
for (int j=1;j<=tot && i*prime[j]<=5000000;j++)
{
vis[i*prime[j]]=true;
if (i%prime[j]) {miu[i*prime[j]]=-miu[i];phi[i*prime[j]]=phi[i]*(prime[j]-1);}
else {miu[i*prime[j]]=0;phi[i*prime[j]]=phi[i]*prime[j];break;}
}
}
for (int i=1;i<=5000000;i++) phi[i]+=phi[i-1],miu[i]+=miu[i-1];
}
int find(int num,int pos,int type)
{
int now=(type==1)?g1[num]:g2[num];
while (now)
{
if (type==1)
{
if (l1[now].id==pos) return now;
else now=l1[now].nxt;
}
else
{
if (l2[now].id==pos) return now;
else now=l2[now].nxt;
}
}
return 0;
}
void add(int now,int pos,long long val,int type)
{
if (type==1)
{
l1[++tot1].id=pos;l1[tot1].val=val;
l1[tot1].nxt=g1[now];g1[now]=tot1;
}
else
{
l2[++tot2].id=pos;l2[tot2].val=val;
l2[tot2].nxt=g2[now];g2[now]=tot2;
}
}
long long get_phi(long long x)
{
if (x<=5000000) return phi[x];
long long reg=find(x%mod,x,1);if (reg) return l1[reg].val;
long long ret=x*(x+1)/2,l=2,r;
while (l<=x)
{
r=x/(x/l);
ret-=get_phi(x/l)*(r-l+1);
l=r+1;
}
return ret;
}
int get_miu(long long x)
{
if (x<=5000000) return miu[x];
long long reg=find(x%mod,x,2);if (reg) return l2[reg].val;
long long ret=1,l=2,r;
while (l<=x)
{
r=x/(x/l);
ret-=get_miu(x/l)*(r-l+1);
l=r+1;
}
return ret;
}
int main()
{
scanf("%d",&t);get_table();
for (int i=1;i<=t;i++)
{
scanf("%lld",&n);
printf("%lld %d\n",get_phi(n),get_miu(n));
}
return 0;
}