解析:
简单的欧拉函数套上一个线性筛。。。
考虑这个方阵的下三角(反正上面也是对称过去的,乘以2就行了),
第
i
i
列除去轴上的和对角线上的点,就还剩
i
i
个点,而如果有,则该点在
(i/gcd(i,j),j/gcd(i,j))
(
i
/
g
c
d
(
i
,
j
)
,
j
/
g
c
d
(
i
,
j
)
)
时被收集,所以第
i
i
列能够收集到的点的个数就是以下与
i
i
<script type="math/tex" id="MathJax-Element-8">i</script>互质的数的个数。
多么明显的欧拉函数。。。
最后加上(1,1)这个在对角线上的东西。。。
代码:
#include<iostream>
#include<cctype>
#include<cstdio>
using namespace std;
#define re register
#define ll long long
#define gc getchar
#define pc putchar
#define cs const
#define st static
inline
ll getint(){
re ll num=0;
re char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);c=gc())num=(num<<1)+(num<<3)+(c^48);
return num;
}
inline
void outint(ll a){
st char ch[23];
if(a==0)pc('0');
while(a)ch[++ch[0]]=(a-a/10*10)^48,a/=10;
while(ch[0])pc(ch[ch[0]--]);
}
bool mark[1005];
int prime[1005],pcnt;
int phi[1005];
ll sum[1005];
inline
void linear_sieves(int len=1000){
mark[1]=true;
phi[1]=1;
for(int re i=2;i<=len;++i){
if(!mark[i])prime[++pcnt]=i,phi[i]=i-1;
for(int re j=1;j<=pcnt&&i*prime[j]<=len;++j){
mark[i*prime[j]]=true;
if(i%prime[j]==0){
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
phi[i*prime[j]]=phi[i]*phi[prime[j]];
}
}
}
inline
void init(){
linear_sieves();
sum[0]=0;
for(int re i=1;i<=1000;++i){
sum[i]=sum[i-1]+phi[i];
}
}
int T;
int main(){
init();
T=getint();
for(int re kase=1;kase<=T;++kase){
int n=getint();
outint(kase),pc(' '),outint(n),pc(' '),outint(sum[n]*2+1),pc('\n');
}
return 0;
}