题意:
作为体育委员,C君负责这次运动会仪仗队的训练。
仪仗队是由学生组成的N * N的方阵,
为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,
根据其视线所及的学生人数来判断队伍是否整齐
现在,C君希望你告诉他队伍整齐时能看到的学生人数。
思路:
观察一下图
就是去掉第一行和第一列,然后求gcd=1的对数
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<queue>
#include<stack>
#include<string>
#include<vector>
#include<map>
#include<set>
using namespace std;
#define lowbit(x) (x&(-x))
typedef long long LL;
const int maxn = 100005;
const int inf=(1<<28)-1;
#define maxp 50005
bool notprimes[maxp];
int primes[maxp];
int mu[maxp];
void get_mu()
{
memset(notprimes,false,sizeof(notprimes));
primes[0]=0;
mu[1]=1;
for(int i=2;i<maxp;++i)
{
if(!notprimes[i])
{
primes[++primes[0]]=i;
mu[i]=-1;
}
for(int j=1;j<=primes[0];++j)
{
if((LL)primes[j]*i>=maxp) break;
notprimes[i*primes[j]]=true;
if(i%primes[j])
mu[i*primes[j]]=-mu[i];
else
{
mu[i*primes[j]]=0;
break;//代表i不是素数,mu[i*primes[j]]必然是0
}
}
}
}
LL Pre[maxp];
int main()
{
get_mu();
Pre[0]=0;
for(int i=1;i<maxp;++i)
Pre[i]=Pre[i-1]+mu[i];
int n;
scanf("%d",&n);
if(n==1)
{
printf("0\n");
return 0;
}
LL Ans=2;
--n;
int last;
for(int i=1;i<=n;i=last+1)
{
last=n/(n/i);
Ans+=(Pre[last]-Pre[i-1])*(n/i)*(n/i);
}
printf("%lld\n",Ans);
return 0;
}