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}
先来说明下题意。告诉一直特定的序列,就是上面那一种,然后告诉你一个正整数n,求出Fn有多少项。
先看上面的序列,可以发现分子跟分母都是不可约分的,对!例如分子为a,分母为b。gcd(a,b)=1。肯定有同学会想的gcd。
但是我们有欧拉函数。
然后就是简单的求欧拉函数的题目了。
有一点要注意的是,由于连续用到了求欧拉函数的值,所以这里用到了打表。以前求欧拉函数的方法用在这里一定会超时的。
下面先看看递推打表求欧拉函数的代码
void Eular()/*打表存phi值*/
{
for(int i = 1; i <= maxn ; i++)phi[i] = i;/*预先置所有数的欧拉函数值为其本身*/
for(int i = 2 ; i <= maxn ; i+=2) phi[i]/=2; /*偶数项可以先约一个2*/
for(int i = 3 ; i <= maxn ; i+=2 )
{
if(i == phi[i])/*如果p是一个正整数且∮(p) = p-1,那么p是素数*/
{
for(int j = i ; j <= maxn ; j+=i)/*遇到这种情况,把这个数的欧拉值改变,同时也把能被该因子整除的数改变*/
{
phi[j] = phi[j]/i*(i-1);
}
}
}
for(int i = 3 ; i <= 1000000 ; i++)
{
phi[i] += phi[i-1];
}
}
下面是完整代码
#include<cstdio>
#include<iostream>
using namespace std;
const int maxn = 1000010;
long long phi[maxn+1];/*因为使用数组是从下标1开始的,所以在创建的时候要多开几位,不然会Runtime error*/
int main()
{
void Eular();
int n;
Eular();
while(cin>>n && n)
{
cout<<phi[n]<<endl;
}
return 0;
}
void Eular()/*打表存phi值*/
{
for(int i = 1; i <= maxn ; i++)phi[i] = i;/*预先置所有数的欧拉函数值为其本身*/
for(int i = 2 ; i <= maxn ; i+=2) phi[i]/=2; /*偶数项可以先约一个2*/
for(int i = 3 ; i <= maxn ; i+=2 )
{
if(i == phi[i])/*如果p是一个正整数且∮(p) = p-1,那么p是素数*/
{
for(int j = i ; j <= maxn ; j+=i)/*遇到这种情况,把这个数的欧拉值改变,同时也把能被该因子整除的数改变*/
{
phi[j] = phi[j]/i*(i-1);
}
}
}
for(int i = 3 ; i <= 1000000 ; i++)
{
phi[i] += phi[i-1];
}
}