对前几行的手算可以得出:
从(0,0)连接到(n,0)到(n,n),斜率为:1 / n , 2 / n ...( n - 1 ) / n
也就是说,凡是分子和分母能够约分的,之前均已有过
那么我们将这个矩形以y=x分为两部分,
对于第n行(列)能连的个数也就是Φn
最后再加上(1,1)的一个点即可
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 const int N=1010; 5 int phi[N],prime[N],flag[N],n[N],ans[N],cnt; 6 int max(int x,int y){ 7 return x>y?x:y; 8 } 9 int main(){ 10 int T,maxl; 11 maxl=cnt=0; 12 scanf("%d",&T); 13 for (int i=1;i<=T;i++){ 14 scanf("%d",&n[i]); 15 maxl=max(maxl,n[i]); 16 } 17 phi[1]=1; 18 ans[1]=1; 19 for (int i=2;i<=maxl;i++){ 20 if (!flag[i]){ 21 cnt++; 22 prime[cnt]=i; 23 phi[i]=i-1; 24 } 25 for (int j=1;j<=cnt;j++){ 26 if (i*prime[j]>maxl) break; 27 flag[i*prime[j]]=1; 28 if (i%prime[j]==0){ 29 phi[i*prime[j]]=phi[i]*prime[j]; 30 break; 31 } 32 else phi[i*prime[j]]=phi[i]*(prime[j]-1); 33 } 34 ans[i]=ans[i-1]+phi[i]; 35 } 36 for (int i=1;i<=T;i++) 37 printf("%d %d %d\n",i,n[i],ans[n[i]]*2+1); 38 return 0; 39 }