一文读懂欧拉函数
歐拉函數(shù)φ(N)表示小于或等于N的正整數(shù)中與N互質(zhì)的數(shù)的個(gè)數(shù)。又稱φ函數(shù)、歐拉商數(shù)。
下面介紹歐拉函數(shù)的幾個(gè)性質(zhì):
我們根據(jù)這幾個(gè)性質(zhì)就可以求出歐拉函數(shù)。
基本思路是首先置φ(N)=N,然后再枚舉素?cái)?shù)p,將p的整數(shù)倍的歐拉函數(shù)φ(kp)進(jìn)行如下操作。
代碼如下:
#include
using?namespace?std;
const?int?MAX?=?1024;
int?N;
int?p[MAX],?phi[MAX];
int?main()
{
????cin?>>?N;
????for(int?i?=?1;?i?<=?N;?i++) // 初始化
????{?p[i]?=?1;?phi[i]?=?i;?}
????p[1]?=?0; // 1不是素?cái)?shù)
????for(int?i?=?2;?i?<=?N;?i++) // 篩素?cái)?shù)
????{
????????if(p[i])
????????{
????????????for(int?j?=?i?*?i;?j?<=?N;?j?+=?i)
????????????{?p[j]?=?0;?}
????????}
????}
????for(int?i?=?2;?i?<=?N;?i++) // 求歐拉函數(shù)
????{
????????if(p[i])
????????{
????????????for(int?j?=?i;?j?<=?N;?j?+=?i) // 處理素因子p[i]
????????????{
????????????????phi[j]?=?phi[j]?/?i?*?(i?-?1); // 先除后乘,防止中間過程超出范圍
????????????}
????????}
????}
????cout?<<?"Primes: "?<<?endl;
????for(int?i?=?1;?i?<=?N;?i++)
????{?if(p[i])?{?cout?<<?i?<<?" ";?}?}
????cout?<<?endl;
????cout?<<?"Euler Phi Function: "?<<?endl;
????for(int?i?=?1;?i?<=?N;?i++)
????{?cout?<<?phi[i]?<<?" ";?}
????return?0;
}
以上是關(guān)于歐拉函數(shù)的求法,對(duì)于它的應(yīng)用,這里暫且介紹一個(gè)——求解原根的個(gè)數(shù)。
對(duì)于原根的定義,我們可以這樣來敘述:
若存在一個(gè)實(shí)數(shù)a,使得( a^i ) mod N,a∈{1,2,3,?,N}的結(jié)果各不相同,我們就成實(shí)數(shù)a為N的一個(gè)原根。
原根的個(gè)數(shù)等于φ(φ(N))。這樣我們就可以很方便的求出原根的個(gè)數(shù)。
代碼如下:
#include
#include
using?namespace?std;
typedef?unsigned?long?long?ull;
ull?N;
ull phi(ull?x);
int?main()
{
????cin?>>?N;
????cout?<<?phi(phi(N))?<<?endl;
????return?0;
}
ull phi(ull?x)
{
????ull?ans?=?x;
????ull?m?=?(ull)sqrt(x);
????for(ull?i?=?2;?i?<<=?m;?i++)
????{
????????if(x?%?i?==?0) // 求素因子
????????{
????????????ans?=?ans?/?i?*?(i?-?1); // 運(yùn)用通項(xiàng)求解歐拉函數(shù)
????????????while(x?%?i?==?0) // 每個(gè)素因子只計(jì)算一次
????????????{?x?/=?i;?}
????????}
????}
????if(x?>?1) // 防質(zhì)數(shù)
????{?ans?=?ans?/?x?*?(x?-?1);?}
????return?ans;
}
轉(zhuǎn)自:ivy-end
http://www.ivy-end.com/archives/1021
總結(jié)
- 上一篇: 魔性十足的数学动态图,这种东西都拿出来分
- 下一篇: 一文读懂 AVL 树