欧拉函数

欧拉函数的定义:

    在数论中,对于正整数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)。注意:每种质因数只有一个。

     例如:

    φ(5)=5×(1-1/5)=4;

         φ(10)=10×(1-1/2)×(1-1/5)=4;

    φ(30)=30×(1-1/2)×(1-1/3)×(1-1/5)=8;

         φ(49)=49×(1-1/7)=42;

欧拉函数的性质:

(1)   p^k型欧拉函数:

若N是质数p(即N=p), φ(n)= φ(p)=p-p^(k-1)=p-1。

若N是质数p的k次幂(即N=p^k),φ(n)=p^k-p^(k-1)=(p-1)p^(k-1)。

(2)mn型欧拉函数

设n为正整数,以φ(n)表示不超过n且与n互素的正整数的个数,称为n的欧拉函数值。若m,n互质,φ(mn)=(m-1)(n-1)=φ(m)φ(n)。

(3)特殊性质:

若n为奇数时,φ(2n)=φ(n)。

对于任何两个互质 的正整数a,n(n>2)有:a^φ(n)=1 mod n (恒等于)此公式即 欧拉定理

当n=p 且 a与素数p互质(即:gcd(a,p)=1)则上式有: a^(p-1)=1 mod n (恒等于)此公式即 费马小定理

欧拉函数的延伸:

小于或等于n的数中,与n互质的数的总和为:φ(x) * x / 2  (n>1)。

欧拉函数模板

#include <iostream>
#include<cstdio>
#include<math.h>
#include<cstring>
#include<vector>
#include<map>
#include<algorithm>
typedef long long LL;

using namespace std;
const int maxn=6000005;
long long f[maxn];
map<string, int>Q;
int e[maxn];
///1、直接求小于或等于n,且与n互质的个数
int Euler(int n)
{
    int res=n;
    for(int i=2; i<=sqrt(n); i++)
    {
        if(n%i==0)
        {
            res=res/i*(i-1);
            while(n%i==0)
                n/=i;
        }
    }
    if(n>1)
        res=res/n*(n-1);
    return res;
}
///2、打表筛选模板:求[1, n]之间每个数的质因数的个数
void euler()
{
    memset(e, 0, sizeof(e));
    e[1]=1;
    for(int i=2; i<maxn; i++)
    {
        if(!e[i])
        {
            for(int j=i; j<maxn; j+=i)
            {
                if(!e[j])
                    e[j]=j;
                e[j]=e[j]/i*(i-1);
            }
        }
    }
}
int main()
{
    int n;
    for(int i=1; i<10; i++)
        printf("%d\n", e[i]);
    while(~scanf("%d", &n))
    {
        printf("%d\n", Euler(n));
    }
    return 0;
}

 http://www.lightoj.com/volume_showproblem.php?problem=1007

1007 - Mathematically Hard
Time Limit: 2 second(s) Memory Limit: 64 MB

Mathematically some problems look hard. But with the help of the computer, some problems can be easily solvable.

In this problem, you will be given two integers a and b. You have to find the summation of the scores of the numbers from a to b (inclusive). The score of a number is defined as the following function.

score (x) = n2, where n is the number of relatively prime numbers with x, which are smaller than x

For example,

For 6, the relatively prime numbers with 6 are 1 and 5. So, score (6) = 22 = 4.

For 8, the relatively prime numbers with 8 are 1, 3, 5 and 7. So, score (8) = 42 = 16.

Now you have to solve this task.

Input

Input starts with an integer T (≤ 105), denoting the number of test cases.

Each case will contain two integers a and b (2 ≤ a ≤ b ≤ 5 * 106).

Output

For each case, print the case number and the summation of all the scores from a to b.

Sample Input

Output for Sample Input

3

6 6

8 8

2 20

Case 1: 4

Case 2: 16

Case 3: 1237

Note

Euler's totient function  applied to a positive integer n is defined to be the number of positive integers less than or equal to n that are relatively prime to n.  is read "phi of n."

Given the general prime factorization of , one can compute  using the formula

///开俩数组就内存超限了= =

#include <iostream>
#include<cstdio>
#include<math.h>
#include<cstring>
#include<vector>
#include<map>
#include<algorithm>
typedef long long LL;

using namespace std;
const int maxn=5000010;
map<string, int>Q;
unsigned long long e[maxn];
void euler()
{
    memset(e, 0, sizeof(e));
    e[1]=1;
    for(int i=2; i<=maxn; i++)
    {
        if(!e[i])
        {
            for(int j=i; j<=maxn; j+=i)
            {
                if(!e[j])
                    e[j]=j;
                e[j]=e[j]/i*(i-1);
            }
        }
    }
    for(int i=1; i<=maxn; i++)
        e[i]=e[i-1]+e[i]*e[i];
}
int main()
{
    euler();
    int T, l, r, cas=1;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d%d", &l, &r);
        printf("Case %d: %llu\n", cas++, e[r]-e[l-1]);
    }
    return 0;
}

 

 

posted @ 2017-07-18 16:46  爱记录一切美好的微笑  阅读(351)  评论(1编辑  收藏  举报