題目描述
BB
其實是一道sb題
1013+10組數據足以把
杜教篩/min25/洲閣篩/反演+篩μ/分塊+篩質數
給送上天了
所以正解肯定是T√n的做法
性質
歐拉函數有一個著名的性質:
證明:
設,則
(nm互質)
所以證得F(n)是積性函數
求(p爲質數)
由於F(n)是積性函數,且F(pk)=pk,所以可以推得F(n)=n(對於任意n)
所以
參考:https://blog.csdn.net/liuzibujian/article/details/81086324
題解
題目的
可以發現,每個質因子的質數除了2
那麼
本質上,枚舉d其實是枚舉n中指數爲1的倍數的約數
由於先前除了2,考慮把d和f(n)的指數都乘以2,這樣得到的實際上是一樣的
所以
沒了
code
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define Len 3162277
using namespace std;
bool f[Len+1];
int p[Len+1];
int phi[Len+1];
int T,N,i,j,k,l,len;
long long n,ans;
void init()
{
int i,j;
memset(f,0,sizeof(f));
len=0;
phi[1]=1;
fo(i,2,Len)
{
if (!f[i])
{
p[++len]=i;
phi[i]=i-1;
}
fo(j,1,len)
if ((long long)i*p[j]<=Len)
{
f[i*p[j]]=1;
phi[i*p[j]]=phi[i]*p[j];
if (!(i%p[j]))
break;
phi[i*p[j]]=phi[i*p[j]]/p[j]*(p[j]-1);
}
else
break;
}
}
int main()
{
// freopen("e.in","r",stdin);
init();
scanf("%d",&T);
for (;T;--T)
{
scanf("%lld",&n);
N=floor(sqrt(n));
ans=0;
fo(i,1,N)
ans+=phi[i]*(n/i/i);
printf("%lld\n",ans);
}
}