生活随笔
收集整理的這篇文章主要介紹了
基础数论(入门)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
基礎數論(入門,貌似還沒)
嫖了學長的pdf
常用運算符
基本常識(就很…)
基本定理(最好有些簡單題來把基本定理練熟)
常用算法
埃氏篩
從整數中篩去合數,留下素數
考慮給定一個素數x那么很明顯所有x的倍數都不是素數,我們只需要枚舉一個系數i,將所有的xi標記為合數即可
復雜度參考前面的常識~O(n log log n)
for(int i
=2;i
<maxn
;++i
) { for(int j
=i
;j
<maxn
;j
+=i
) { notPrime
[j
]=1; }
}
一點點小優化,可以發現對于所有j<i^2, 一定在之前已經被篩掉l了
所以可從i^2開始篩
線性篩
大部分只需要判斷素數的問題,埃氏篩已經夠優秀了
但是一部分題需要更大的素數范圍或需要快速求一些積性函數的問題,此時需要用到線性篩
反正我學會線性篩就再沒用過埃氏篩
我們發現埃氏篩在篩的過程中,同一個數字會被篩去很多次,正是這一步限制了它的效率
線性篩的優化在于每個數字只會被它的最小素因子篩去,每個數字只會被篩去一次
具體做法:假設當前枚舉到整數i,枚舉當前所有小于等于i的素數記作pj,若i不是pj的倍數,將ipj篩去,此時pj是整數ipj的最小素因子
因為每個數只會被它的最小素因子篩去,復雜度~O(n)
for(int i
=2;i
<maxn
;++i
) { if(!notPrime
[i
]) { prime
[tot
++] = i
; }for(int j
=0;j
<tot
&&i
*prime
[j
]<maxn
;++j
) { notPrime
[i
*prime
[j
]]=1; if(i
%prime
[j
]==0) break; }
}
用線性篩求積性函數
for (int i
= 2;i
< maxn
;++i
) {if (!notPrime
[i
]) {prime
[tot
++] =i
;f
[i
] =func();g
[i
] = f
[i
];}for (int j
= 0;j
< tot
&& i
* prime
[j
] <maxn
;++j
) {notPrime
[i
* prime
[j
]] = 1;if (i
% prime
[j
] == 0) {int ret
= 1, x
= i
;while (x
% prime
[j
] == 0) {ret
*= prime
[j
];x
/= prime
[j
];}f
[i
* prime
[j
]] = f
[i
] / g
[i
] * f
[ret
];g
[i
* prime
[j
]] = f
[ret
];break;}f
[i
* prime
[j
]] = f
[i
] * f
[prime
[j
]];g
[i
* prime
[j
]] = f
[prime
[j
]];}}
一般來說這些函數都會有一些方便計算的性質,中間求ret的部分可以被極大的簡化
快速冪
int quickpow(int a
, int n
, int mod
) {int ans
= 1;while (n
) {if (n
& 1) ans
= ans
* a
% mod
;a
= a
* a
% mod
;n
>>= 1;}return ans
;}
矩陣快速冪
輾轉相除法/歐幾里得算法
int gcd(int a
, int b
) { return b
? gcd(b
, a
% b
) : a
; }
擴展歐幾里得
int exgcd(int a
, int b
, int &x
, int &y
) {if (b
== 0) {x
= 1, y
= 0;return a
;}int d
= exgcd(b
, a
% b
, x
, y
);int tmp
= x
;x
= y
;y
= tmp
- y
* (a
/ b
);return d
;}
中國剩余定理
gcd性質
1、結合律,gcd(a,b,c)=gcd(a,gcd(b,c))=gcd(gcd(a,b),c)
2、gcd(a,b)=gcd(b,a/b)=gcd(b,∣a?b∣)=gcd(a,∣a?b∣)
總結
以上是生活随笔為你收集整理的基础数论(入门)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。