1. 程式人生 > >【數論】線性篩與積性函式

【數論】線性篩與積性函式

尤拉函式:

定義φ(n)表示1~n中和n互素的數目
性質
首先可以根據概念得知,當n為素數時,顯然ϕ(n)=n1
尤拉函式是個不完全積性函式,證明過程較複雜,貼個連結趕緊跑
根據它積性函式的性質和唯一分解定理,我們就可以把任意一個φ(n)分解為

φ(n)=φ(pkii)
那麼我們只需求出φ(pk)就可以求出任意數的尤拉函式值
1~pk一共有pk個數,其中是p的倍數的有{p,2p,3p,pk}共pk1個數,據上述
這裡寫圖片描述
我們就得到了尤拉函式的一般求解公式

求解時分三種情況:

  1. 當i為素數時,顯然ϕ(i)=i1
  2. i%prime[j]0時,prime[j]一定是i
    ×prime[j]
    的最小的質因子,所以有gcd(i,prime[j])=1,由積性函式的性質可得ϕ[iprime[j]]=ϕ[i](prime[j]1)
  3. i×prime[j]=0時,根據尤拉函式的定義式:ϕ[n]=n×ki=1(11pi),故若i×prime[j]=0 , prime[j]在之前已經篩過,iprime[j]的質因子數不變
    ϕ[iprime[j]]=ϕ[i]×prime[j]

下面是線性篩+求尤拉函式\莫比烏斯函式\約數個數的程式碼

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm> using namespace std; const int N=10000010; int prime[N],cnt,phi[N],mob[N],fac[N],d[N]; bool isprime[N]; void Get_table() { mob[1]=1; phi[1]=1; fac[1]=1; for(int i=2;i<=N;i++) { if(!isprime[i]) { prime[++cnt]=i; phi[i]=i-1
; mob[i]=-1; fac[i]=2; d[i]=1; } for(int j=1;j<=cnt&&(long long)i*prime[j]<=N;j++) { isprime[i*prime[j]]=1; if(i%prime[j]==0) { phi[i*prime[j]]=phi[i]*prime[j]; mob[i*prime[j]]=0; fac[i*prime[j]]=fac[i]/(d[i]+1)*(d[i]+2); d[i*prime[j]]=d[i]+1; break; } phi[i*prime[j]]=phi[i]*(prime[j]-1); mob[i*prime[j]]=-mob[i]; fac[i*prime[j]]=fac[i]*2; d[i*prime[j]]=1; } } } int main() { int n; Get_table(); while(cin>>n) cout<<phi[n]<<" "<<mob[n]<<" "<<fac[n]<<endl; return 0; }

相關推薦

數論線性函式

尤拉函式: 定義:φ(n)表示1~n中和n互素的數目 性質: 首先可以根據概念得知,當n為素數時,顯然ϕ(n)=n−1 尤拉函式是個不完全積性函式,證明過程較複雜,貼個連結趕緊跑 根據它積性函式的性質和唯一分解定理,我們就可以把任意一個φ(n)

數論線性質數

一次 數論 [1] utc syn else == ring tdi 核心思想: 保證每個合數只會被它的最小質因數篩去,因此每個數只會被標記一次,所以時間復雜度是O(n) 此過程中保證了兩點: 合數一定被幹掉了... 每個數都沒有被重復地刪掉

數論線性素數,線性尤拉函式,求前N個數的約數個數

先來最基本的線性篩素數,以後的演算法其實都是基於這個最基本的演算法: #include<stdio.h> #include<string.h> #define M 10000000 int prime[M/3]; bool flag[M]; void

數論——模板線性素數

題目來源 洛谷P3383【模板】線性篩素數 https://www.luogu.org/problem/show?pid=3383 思路 線性篩素數模板題 時間複雜度:O(n) 程式碼(C++

P3383 模板線性素數

... right else cst pre left 數據 ret col 題目描述 如題,給定一個範圍N,你需要處理M個某數字是否為質數的詢問(每個數字均在範圍1-N內) 輸入輸出格式 輸入格式: 第一行包含兩個正整數N、M,分別表示查詢的範圍和查詢

luogu_3383 模板線性素數

bre rime esp turn bit %d rim style clu 1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,m,cnt,prime[10000010],noprime[1

luogu 3383模板線性素數

100% put pre esp log main col i++ 每一個 題目描述 如題,給定一個範圍N,你需要處理M個某數字是否為質數的詢問(每個數字均在範圍1-N內) 輸入輸出格式 輸入格式: 第一行包含兩個正整數N、M,分別表示查詢的範圍和查詢的個數。 接

洛谷 P3383 模板線性素數

toolbar left 整數 show scan fin names 一行 bar P3383 【模板】線性篩素數 題目描述 如題,給定一個範圍N,你需要處理M個某數字是否為質數的詢問(每個數字均在範圍1-N內) 輸入輸出格式 輸入

模板線性(洛谷P3383)

Description   如題,給定一個範圍\(N\),你需要處理\(M\)個某數字是否為質數的詢問(每個數字均在範圍\(1-N\)內) Input   第一行包含兩個正整數\(N\)、\(M\),分別表示查詢的範圍和查詢的個數。   接下來\(M\)行每行包含一個不小於1且不大於\(N\)的整數,即

基礎題 P3383 模板線性素數 洛谷 簡單

題目描述 如題,給定一個範圍N,你需要處理M個某數字是否為質數的詢問(每個數字均在範圍1-N內) 輸入輸出格式 輸入格式: 第一行包含兩個正整數N、M,分別表示查詢的範圍和查詢的個數。 接下來M行每行包含一個不小於1且不大於N的整數,即詢問該數是否為質數。 輸出格式: 輸出包含M

[洛谷]P3383 模板線性素數 (#數學 -1.15)

題目描述 如題,給定一個範圍N,你需要處理M個某數字是否為質數的詢問(每個數字均在範圍1-N內) 輸入輸出格式 輸入格式: 第一行包含兩個正整數N、M,分別表示查詢的範圍和查詢的個數。 接下來M行每行包含一個不小於1且不大於N的整數,即詢問該數是否為質數。 輸出格式:

luogu P3383 模板線性素數

強推洛穀日報 寫的超棒! (洛穀日報裡的文章都超好 (所以我就不說什麼了 質數判定方法   #include<cstdio> #include<cstring> using namespace std; #define maxn 10000010 in

模板線性素數(埃+歐

本來打算自己寫一篇的,但在找埃篩的程式碼時找到了一篇不錯的題解,修改了一點內容上的表述分享出來,原作者的洛谷ID為 dormantbs 我們常說的線篩是指線上性時間內把素數篩出來的過程,這裡介紹兩種篩法. 一般篩法(埃拉託斯特尼篩法,之後簡稱為埃篩): 基

莫比烏斯反演函式部分(轉載)

莫比烏斯與積性函式 之前做過不少的數論題,關於莫比烏斯與積性函式的數論題挺多的。。。特地過來總結一下。。當作自己的一個回顧了-_- 先安利一下神犇tls的部落格和神犇PoPoQQQ的pdf !膜拜tls…跪popoqqq… 還有IOI金牌神犇任之州的集訓隊論文,都

hdu 5728 PowMod數論尤拉函式尤拉降冪遞迴取模尤拉函式

【連結】 http://acm.hdu.edu.cn/showproblem.php?pid=5728 【題意】 n是無平方因子的數 定義k=∑mi=1φ(i∗n) mod 1000000007,求K^k^k^k......%p 【思路】 先尤拉性質求出k

數學數論素數的線性

寫在前面   記錄了個人的學習過程,同時方便複習   素數的線性篩法   有時候需要篩出來一張素數表,即1~n範圍內的所有素數   一個個列舉判斷是否為素數顯然太慢     於是經過仔細的研究之後,發現如果存在正整數k(k>2)不是素數,那麼它的因子裡面一

hdu 5728 PowMod數論尤拉函式尤拉降冪遞迴取模尤拉函式

【連結】 【題意】 n是無平方因子的數 定義k=∑mi=1φ(i∗n) mod 1000000007,求K^k^k^k......%p 【思路】 先尤拉性質求出k,再用尤拉降冪,A^B=A^B%phi(C)+phi(C)  (mod C)求出答案 ∑(i=1~

HDU 5382 GCD?LCM! (數論函式

GCD?LCM! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 316    Accepted Submission(s): 200 O

總結函式字首和(杜教

前言: 據CCH和LJH說,杜教篩似乎是一個非常套路的東西,幾乎所有的杜教篩的題目推理方式都是一模一樣的(但實測有些推理還是很噁心的)。所以複習杜教篩不需要太多時間,粗略看一遍,留下印象即可。 杜教篩其實是一種簡化運算的推理方式,它的使用條件並不僅限於積