题目大意是让我们求Σ(1<=i<=n)Σ(1<=j<i)gcd(i,j)==1,这题不就是一道欧拉函数的裸题吗?
欧拉函数(φ)定义:φ(n)=Σgcd(n,i) (1<=i<n)
然后有以下定理:
- 若p为素数,则φ(p)=p-1
- 若a,b互质,则φ(a*b)=φ(a)*φ(b),即φ为积性函数
- 若a%b==0,则φ(a*b)=φ(a)*b
我们可以把欧拉函数写在线性筛里,直接O(n)求出n以内所有数的欧拉函数值,对于每次给出的n直接输出答案即可。
附上AC代码:
#include <cstdio>
using namespace std;
const int N=1010;
int t,n,a[N],num,phi[N],ans;
bool b[N];
inline void prime(){
phi[1]=1;
for (int i=2; i<=N; ++i){
if (!b[i]) a[++num]=i,phi[i]=i-1;
for (int j=1; j<=num&&i*a[j]<=N; ++j){
b[i*a[j]]=1;
if (i%a[j]==0){
phi[i*a[j]]=phi[i]*a[j];
break;
}
else phi[i*a[j]]=phi[i]*(a[j]-1);
}
}
return;
}
int main(void){
prime();
scanf("%d",&t);
for (int i=1; i<=t; ++i){
scanf("%d",&n),ans=0;
for (int j=1; j<=n; ++j) ans+=phi[j];
printf("%d %d %d\n",i,n,ans*2+1);
}
return 0;
}