跟这题一样的 [bzoj2818: Gcd] gcd(x,y)=质数, 1<=x,y<=n
的对数
作为体育委员,C君负责这次运动会仪仗队的训练。仪仗队是由学生组成的N * N的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,根据其视线所及的学生人数来判断队伍是否整齐(如下图)。 现在,C君希望你告诉他队伍整齐时能看到的学生人数。
要先发现一个规律。在手动画出几组之后你就会发现可以被看到的都是那些x/y为最简式的形式。因为,如果可以在化简则说明其最简式一定被看过了。所以,题目就转换成了求解在N范围内x,y互质的个数。而数据具有对称性,所以最后结果是*2而其中有一个(1,1)是特别的要减1而最后的结果存在(0,1),(1,0)这个特殊组所以在+2.整理后最后式子为res*2 + 1
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;
const int MAXN = 40000 + 10;
int n,primes;
LL f[MAXN],prime[MAXN],phi[MAXN];
bool com[MAXN];
void init(){
memset(com,0,sizeof(com));
primes = 0;
phi[1] = 1;
for(int i = 2;i < MAXN;++i){
if(!com[i]){
prime[primes++] = i;
phi[i] = i - 1;
}
for(int j = 0;j < primes&&i*prime[j] < MAXN;++j){
com[i*prime[j]] = true;
if(i % prime[j])
phi[i*prime[j]] = phi[i] * (prime[j] - 1);
else { phi[i*prime[j]] = phi[i] * prime[j]; break;}
}
}
}
int main()
{
init();
while(~scanf("%d",&n)){
if(n == 1){
puts("0");
continue;
}
if(n == 2){
puts("3");
continue;
}
LL ans = 0;
for(int i = 0;i < n;++i) ans += phi[i];
printf("%lld\n",ans<<1|1);
}
return 0;
}