题干:
给你一个n,设a,b为任意大于零小于等于n的整数,求a/b能组成多少种不同的数。
例如:F2 = {1/2}
F3 = {1/3, 1/2, 2/3}
F4 = {1/4, 1/3, 1/2, 2/3, 3/4}
F5 = {1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5}
2 <= n <=
1
0
6
10^6
106
思路:
观察前四项,我们可以发现,后一项的个数为前一项的个数加上本项中与前一项不相等的。
即F5=F4+4(1/5,2/5,3/5,4/5) ,然后可得,本项中额外加的部分为n的欧拉函数(即比n小的数与n互素的个数)(只有两个数互素才能是a/b不能约分)。
所以我们只需要打表出n的欧拉函数,然后取前缀和,最后查表就行。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int mx = 1e6+10;
long long ol[mx];
void getol()
{
memset(ol,0,sizeof(ol));
ol[1]=1;
for(long long i=2;i<mx;i++){
if(!ol[i])
{
for(long long j=i;j<mx;j+=i){
if(!ol[j])
ol[j]=j;
ol[j]=ol[j]/i*(i-1);
}
}
}
}
int main()
{
int n,olc;
getol();
//printf("%d\n",ol[3]);
for(long long i=3;i<mx;i++)
ol[i]+=ol[i-1];
while(scanf("%d",&n))
{
if(n==0) break;
printf("%lld\n",ol[n]);
}
return 0;
}