题目:click
开始分析,n的范围肯定不能取枚举斜率做,首先需要看到那么每个点与左下角的点的斜率必定不同,也就不共线,上图的线连接的太乱,我们可以除去线,枚举前面几个n会发现他们是对称的,所以我们从一边入手即可。
为了让k不同,其实本质就是
y
1
−
y
2
x
1
−
x
2
\frac{y1-y2}{x1-x2}
x1−x2y1−y2不同,化简到最简分数也就是上下同除以gcd,那么发现就是互质的数,考虑每一列分析,x=2时,也就是与(1-1)与1互质的数,依次类推。
要是熟悉欧拉函数的同学,看列的时候可以看出规律了。
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int MAXN=262144*2+10;
const double PI=acos(-1.0);
const long double eps=1e-12;
const int MAX=4e4+5;
int euler[400100];
void Euler()
{
euler[1]=1;
for(int i=2;i<MAX;i++)
euler[i]=i;
for(int i=2;i<MAX;i++)
if(euler[i]==i)//即这个数是素数
for(int j=i;j<MAX;j+=i)
euler[j]=euler[j]/i*(i-1);
}
int main()
{
Euler();
int n,i,j;
scanf("%d",&n);
if(n==1)
{
printf("0");
return 0;
}
int sum=0;
for(i=1;i<n;i++)
{
sum+=euler[i];
}
sum*=2;
sum++;
printf("%d",sum);
return 0;
}