1. 程式人生 > >尤拉函式( 數論) + 唯一分解定理

尤拉函式( 數論) + 唯一分解定理

尤拉函式

初步認識:

數論,對正整數n,尤拉函式是小於n的正整數中與n互質的數的數目(φ(1)=1)。此函式以其首名研究者尤拉命名(Euler's totient function),它又稱為Euler's totient function、φ函式、尤拉商數等。 例如φ(8)=4,因為1,3,5,7均和8互質。 從尤拉函式引伸出來在環論方面的事實和拉格1.

通式:

 

其中p1, p2……pn為x的所有質因數,x是不為0的整數。

φ(1)=1(和1互質的數(小於等於1)就是1本身)。

注意:每種質因數只一個。 比如12=2*2*3那麼φ(12)=12*(1-1/2)*(1-1/3)=4

若n是質數p的k次冪,

  

,因為除了p的倍數外,其他數都跟n互質。

設n為正整數,以 φ(n)表示不超過n且與n互素的正整數的個數,稱為n的尤拉函式值

φ:N→N,n→φ(n)稱為尤拉函式。

尤拉函式是積性函式——若m,n互質,

 

特殊性質:當n為奇數時,

  

, 證明與上述類似。

若n為質數則

 

求法模板:

int ou_lar( )
{
    int i , j, k;
    memset( enlur, 0, sizeof( enlur ));
    memset( visit  , 0, sizeof( visit ));
    visit[1] = 1;
    enlur[1] = 0;
    for( i = 2; i<=1000005; i++)
    {
        if( !enlur[i] )
        {
            visit[i] = 1;
            enlur[i] = i-1;
            for( j = 2*i; j <= 1000005; j = j+i)
            {
                if( !visit[j] )
                {
                    enlur[j] = j;
                    visit[j] = 1;
                }
                enlur[j] = enlur[j]/i*( i-1 );
            }
        }
    }
}

例題跟蹤:

Bamboo Pole-vault is a massively popular sport in Xzhiland. And Master Phi-shoe is a very popular coach for his success. He needs some bamboos for his students, so he asked his assistant Bi-Shoe to go to the market and buy them. Plenty of Bamboos of all possible integer lengths (yes!) are available in the market. According to Xzhila tradition,

Score of a bamboo = Φ (bamboo's length)

(Xzhilans are really fond of number theory). For your information, Φ (n) = numbers less than n which are relatively prime (having no common divisor other than 1) to n. So, score of a bamboo of length 9 is 6 as 1, 2, 4, 5, 7, 8 are relatively prime to 9.

The assistant Bi-shoe has to buy one bamboo for each student. As a twist, each pole-vault student of Phi-shoe has a lucky number. Bi-shoe wants to buy bamboos such that each of them gets a bamboo with a score greater than or equal to his/her lucky number. Bi-shoe wants to minimize the total amount of money spent for buying the bamboos. One unit of bamboo costs 1 Xukha. Help him.

Input

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

Each case starts with a line containing an integer n (1 ≤ n ≤ 10000) denoting the number of students of Phi-shoe. The next line contains n space separated integers denoting the lucky numbers for the students. Each lucky number will lie in the range [1, 106].

Output

For each case, print the case number and the minimum possible money spent for buying the bamboos. See the samples for details.

Sample Input

3

5

1 2 3 4 5

6

10 11 12 13 14 15

2

1 1

Sample Output

Case 1: 22 Xukha

Case 2: 88 Xukha

Case 3: 4 Xukha

/////互質即只有公因數1;若n為素數 則尤拉值即為 n-1

/題意  竹子長度為k 得分為小於等於k並且與k互質的數的個數
///即為尤拉函式的值 , 現在給定n個幸運數字 要求所買竹子的得分必須大於等於
///對應的數字 並且單位長度為1元 求最小花費



///思路 : 尤拉函式打表 , 要想得分大於等於n  則竹子長度必須大於等於n
///即逐漸找尤拉函式值大於n的相加

 

///tip; 本題是小於n的與n互質的個數  所以1時為0 其餘不變

程式碼

#include<cstdio>
#include<cstring>
#include<map>
#include<algorithm>
#include <queue>
using namespace std;
int enlur[1000005];
int visit[1000005];
int ou_lar( )
{
    int i , j, k;
    memset( enlur, 0, sizeof( enlur ));
    memset( visit  , 0, sizeof( visit ));
    visit[1] = 1;
    enlur[1] = 0;
    for( i = 2; i<=1000005; i++)
    {
        if( !enlur[i] )
        {
            visit[i] = 1;
            enlur[i] = i-1;
            for( j = 2*i; j <= 1000005; j = j+i)
            {
                if( !visit[j] )   以便賦初值
                {
                    enlur[j] = j;
                    visit[j] = 1;
                }
                enlur[j] = enlur[j]/i*( i-1 );
            }
        }
    }
}

int main()
{
    int t;
    ou_lar();
    scanf("%d", &t);
    int cn = 1;
    int n , m;
    int i , j;
    while( t-- )
    {
        long long int sum = 0;
        scanf("%d", &n);
        for( i = 0; i<n; i++)
        {
            scanf("%d", &m);
            for( j = m; j; j++)
            {
                if( enlur[j] >= m )
                {
                    sum = sum + j;
                    break;
                }
            }
        }
        printf("Case %d: %lld Xukha\n", cn++, sum);
    }
    return 0;
}

唯一分解定理

算術基本定理(唯一分解定理)

一句話: 
   

認識:  
任何大於1的自然數,都可以唯一分解成有限個質數的乘積

例如對於大於1的自然數n, 
來自維基百科 
這裡P均為質數,其指數a是正整數。 
這樣的分解稱為的標準分解式

唯一分解定理的基本應用:

① 一個大於1的正整數N,將其化成標準分解式N = p1^a1 * p2^a2 *....pn^an(例如24 = 2^3 * 3^1),那麼N的正因數個數為σ1(N) = (a1+1)*(a2+1)*....(an+1)( 因子各不相同)

(p1..pn為N的素因子,a1...an為各素數的冪)

② 所有正因數之和為σ2 = (1+p1+p1^2+...p1^a1)* (1+p2+p2^2+....p2^a2) * ..... *(1+pn+pn^2+.....pn^an);當σ2(N) = 2*N時稱N為完全數,是否存在奇完全數,尚不明確

③ 利用算數基本定理可以重新定義a和b的最大公因子(a,b)和最小公倍數(a,b), a*b= 最大公因子(a,b)* 最小公倍數(a,b)

 唯一分解定理模板

typedef long long ll;
ll fac[10050], num;//素因數,素因數的個數
void init(ll n) {//唯一分解定理
    num = 0;
    ll cpy = n;
    int m = (int)sqrt(n + 0.5);
    for (int i = 2; i <= m; ++i) {
        if (cpy % i == 0) {
            fac[num++] = i;
            while (cpy % i == 0) cpy /= i;
        }
    }
    if (cpy > 1) fac[num++] = cpy;
}