分析题意及样例之后可知,应该是可以写出递推公式,f(i) = f(i-1)+ euler(i),
其中f(i)是输出的结果,f(i-1)是上一次的结果,euler(i)是小于i的正整数中与i互质的整数个数,eluer可以由欧拉公式求出
欧拉函数的公式
φ函数的值 通式:φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn),其中p1, p2……pn为x的所有质因数,x是不为0的整数。φ(1)=1(唯一和1互质的数(小于等于1)就是1本身)。 (注意:每种质因数只一个。比如12=2*2*3那么φ(12)=12*(1-1/2)*(1-1/3)=4
知道了这些之后,还需要使用筛选法快速判断素数才能大大降低实现复杂度
#include <iostream>
#include <string>
#include <string.h>
#include <queue>
#include <vector>
#include <stdio.h>
#include <math.h>
#include <list>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
using namespace std;
const int SIZE = 1000000;
bool is_prime[SIZE+2];
int prime[SIZE+2];
long long cc[SIZE+2];
int euler[SIZE+2];
int primenum = 0;
void preprocess()
{
for(int i=0;i<=SIZE;i++)
is_prime[i] = true;
for (int i = 2;i <= SIZE;i++)
{
if (is_prime[i])
{
prime[primenum] = i;
primenum++;
}
for (int j = 0,k; (j < primenum) && (k = i * prime[j]) <= SIZE;j++)
{
is_prime[k] = false;
if(i % prime[j] == 0) break;
}
}
for(int i=2;i<=SIZE;i++)
euler[i] = i;
for(int i = 0;i < primenum;++i)
{
int p = prime[i];
for(int j = p;j <= SIZE;j += p)
{
if(j % p != 0)
continue;
euler[j] = euler[j] / p * (p-1);
}
}
}
int main()
{
int n;
cin>>n;
cc[2] =1;
preprocess();
for(int i=3;i<=SIZE;i++)
cc[i] = cc[i-1]+euler[i];
while(n!=0)
{
cout<<cc[n]<<endl;
cin>>n;
}
}