尤拉函式 素數篩

2022-09-16 19:15:10 字數 3093 閱讀 3928

尤拉發現求小於等於n的正整數中有多少個數與n互質可以用這個公式:

euler(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…(1-1/pn),其中p1,p2……pn為x的所有素因數,x是不為0的整數。euler(1)=1(唯一和1互質的數就是1本身)。 

尤拉公式的延伸:乙個數的所有質因子之和是euler(n)*n/2。

其實直接看模板加註解想想就能看懂

篩選的原理就是找出n的因子,剔除含有n的因子的數,即剔除與n不互質的數

既然是求與n互質的個數,那我們可以直接篩選,看模板:

int phi(int n)

{    int res=n;                  /假設現有n個數與n互質,開始篩選剔除

for(i=2;i*i<=n;i++)

{    if(n%i==0)                /若這個數是n的因子,減去n以下含有這個因子的數個數,假設n=8,小於等於8,2為公因子的有8/2=4個

{   res-=res/i;

while(n%i==0)            /將n不斷整除這個因子  

n=n/i;

if(n>1)             /若n大於1,則此時的n也是乙個除1以外的因子

res-=res/n;            

return res;

有時候還用到多個數的尤拉值,因此需要對1到n的數都求出尤拉值,就是打表。

將1到n的尤拉值求出並儲存到陣列,篩選法,**:

void phi(int n)                         上邊的看懂了,下邊這個求多個數的也類似

{   for(int i=1;i<=n;i++)

p[i]=i;                   賦原值

for(int i=2;i<=n;i++)

if(p[i]==i)                

{   for(int j=i;j<=n;j+=i)          篩選

p[j]=p[j]-p[j]/i;

原理就是若乙個數有除1和它本身以外的因子就將它標記不是素數,最後無標記的就是素數。

直接看**加註解:

#include

#include

#define max 1000001

int flag[max];

int main()

{    memset(flag,0,sizeof(flag));

flag[1]=1;               /1代表不是素數,0代表是素數

for(int i=4;iflag[i]=1;              /先將偶數先標記不是

for(int i=3;i*ifor(int j=i*i;jflag[j]=1;

int n;                           

while(cin>>n)

{   if(flag[n]==0)

cout<<"yes"cout<<"no"《素數篩常用於讓你判斷大量素數,或求大量素數,當然如果數目很少,就按常規判斷就好了

尤拉發現求小於等於n的正整數中有多少個數與n互質可以用這個公式:

euler(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…(1-1/pn),其中p1,p2……pn為x的所有素因數,x是不為0的整數。euler(1)=1(唯一和1互質的數就是1本身)。 

尤拉公式的延伸:乙個數的所有質因子之和是euler(n)*n/2。

其實直接看模板加註解想想就能看懂

篩選的原理就是找出n的因子,剔除含有n的因子的數,即剔除與n不互質的數

既然是求與n互質的個數,那我們可以直接篩選,看模板:

int phi(int n)

{    int res=n;                  /假設現有n個數與n互質,開始篩選剔除

for(i=2;i*i<=n;i++)

{    if(n%i==0)                /若這個數是n的因子,減去n以下含有這個因子的數個數,假設n=8,小於等於8,2為公因子的有8/2=4個

{   res-=res/i;

while(n%i==0)            /將n不斷整除這個因子  

n=n/i;

if(n>1)             /若n大於1,則此時的n也是乙個除1以外的因子

res-=res/n;            

return res;

有時候還用到多個數的尤拉值,因此需要對1到n的數都求出尤拉值,就是打表。

將1到n的尤拉值求出並儲存到陣列,篩選法,**:

void phi(int n)                         上邊的看懂了,下邊這個求多個數的也類似

{   for(int i=1;i<=n;i++)

p[i]=i;                   賦原值

for(int i=2;i<=n;i++)

if(p[i]==i)                

{   for(int j=i;j<=n;j+=i)          篩選

p[j]=p[j]-p[j]/i;

原理就是若乙個數有除1和它本身以外的因子就將它標記不是素數,最後無標記的就是素數。

直接看**加註解:

#include

#include

#define max 1000001

int flag[max];

int main()

{    memset(flag,0,sizeof(flag));

flag[1]=1;               /1代表不是素數,0代表是素數

for(int i=4;iflag[i]=1;              /先將偶數先標記不是

for(int i=3;i*ifor(int j=i*i;jflag[j]=1;

int n;                           

while(cin>>n)

{   if(flag[n]==0)

cout<<"yes"cout<<"no"《素數篩常用於讓你判斷大量素數,或求大量素數,當然如果數目很少,就按常規判斷就好了

埃及篩素數 尤拉篩函式

線性篩素數 prime陣列中的素數是遞增的,當i能整除prime j 那麼i prime j 1 這個合數肯定被prime j 乘以某個數篩掉。因為i中含有prime j prime j 比prime j 1 小,即i k prime j 那麼i prime j 1 k prime j prime ...

csu(尤拉函式 篩素數)

這真是一道好題啊!讓我wa了那麼多次,wa的原因是 大於根號n的質因子有且只有乙個,而我一開始都不懂這一點 題目鏈結 題意 輸入乙個n,a是n的所有因子之和,b是所有與n互質的數之和,求a b b比較容易求,所以先分析一下如何求b,首先我們要知道乙個結論如果x與n互質,那麼n x與n也互質,所以b ...

由素數篩法到尤拉函式(尤拉函式,線性篩)

蒟蒻最近準備狂補數學啦tat 基於篩素數,可以同時快速求出尤拉函式。於是蒟蒻準備從這裡入手,整理一下實現的思路。傳統篩素數的做法 埃式篩 是,利用已知的素數,去篩掉含有此質因子的合數,十分巧妙。由於不是本文的重點,就只貼一下 吧 include include define r register i...