在数论中,对于正整数N,少于或等于N ([1,N]),且与N互质的正整数(包括1)的个数,记作φ(n)。
φ函数的值:
φ(x)=x(1-1/p(1))(1-1/p(2))(1-1/p(3))(1-1/p(4))…..(1-1/p(n))
其中p(1),p(2)…p(n)为x的所有质因数;x是正整数; φ(1)=1(唯一和1互质的数,且小于等于1)。注意:每种质因数只有一个。
例如:
φ(10)=10×(1-1/2)×(1-1/5)=4;
1 3 7 9
φ(30)=30×(1-1/2)×(1-1/3)×(1-1/5)=8;
φ(49)=49×(1-1/7)=42;
https://www.cnblogs.com/handsomecui/p/4755455.html
https://blog.csdn.net/sentimental_dog/article/details/52002608
有一种很快的方法在筛素数的同时求出所有数的欧拉函数.
φ(n)=n*(1-1/p1)(1-1/p2)....(1-1/pk),其中p1、p2…pk为n的所有素因子。
比如:φ(12)=12*(1-1/2)(1-1/3)=4。
利用这个就比较好求了,可以用类似求素数的筛法。
先筛出N以内的所有素数,再以素数筛每个数的φ值。
比如求10以内所有数的φ值:
设一数组phi[11],赋初值phi[1]=1,phi[2]=2...phi[10]=10;
然后从2开始循环,把2的倍数的φ值*(1-1/2),则phi[2]=2*1/2=1,phi[4]=4*1/2=2,phi[6]=6*1/2=3....;
再是3,3的倍数的φ值*(1-1/3),则phi[3]=3*2/3=2,phi[6]=3*2/3=2,phi[9]=.....;
再5,再7...因为对每个素数都进行如此操作,因此任何一个n都得到了φ(n)=n*(1-1/p1)(1-1/p2)....(1-1/pk)的运算
觉得这个“筛”还是比较好用的,以前求数的所有因子之和也是用的它。
代码如下:
求法模板:
int ou_lar( )
{
int i , j, k;
memset(oula,0,sizeof(oula));
for(i=2;i<1000005;i++)
if(!oula[i])
{
for(j=i;j<1000005;j+=i)
{
if(!oula[j])
oula[j]=j;
oula[j]=(oula[j]/i)*(i-1);
}
}
}
}
int Euler(int n)
{
int ret=n;
for(int i=2; i<=sqrt(n); i++)
{
if(n%i==0)
{
ret=ret/i*(i-1);//先进行除法防止溢出(ret=ret*(1-1/p(i)))
while(n%i==0)
n/=i;
}
}
if(n>1)
ret=ret/n*(n-1);
return ret;
}
The Farey Sequence Fn for any integer n with n >= 2 is the set of irreducible rational numbers a/b with 0 < a < b <= n and gcd(a,b) = 1 arranged in increasing order. The first few are
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}
You task is to calculate the number of terms in the Farey sequence Fn.
Input
There are several test cases. Each test case has only one line, which contains a positive integer n (2 <= n <= 10 6). There are no blank lines between cases. A line with a single 0 terminates the input.
Output
For each test case, you should output one line, which contains N(n) ---- the number of terms in the Farey sequence Fn.
Sample Input
2
3
4
5
0
Sample Output
1
3
5
9
题意:本题就是求解前n项欧拉函数值的和
普通做法肯定会超时,已试.....
本题代码:
#include
#include
#include
using namespace std;
#define ll long long
ll oula[1000005];
int main()
{
int i,j;
memset(oula,0,sizeof(oula));
for(i=2;i<1000005;i++)
if(!oula[i])
{
for(j=i;j<1000005;j+=i)
{
if(!oula[j])
oula[j]=j;
oula[j]=(oula[j]/i)*(i-1);
}
}
ll t;
while(~scanf("%lld",&t)&&t)
{
ll m=0;
for(i=2;i<=t;i++)
m+=oula[i];
printf("%lld\n",m);
}
return 0;
}