唯一分解定理
n=i∏piαiνp(i)(n)=αi
素数
Fermat 素性检验:检验 an−1≡1(modn)。
二次探测定理:检验 x2≡1(modn)⟹x≡1(modn)∨x≡n−1(modn)。
上述检验若失败则说明 n 必不是质数。
Miller Rabin
分解 Fermat 素性检验中的指数,n−1=u×2t。
对于一个底数 a,求出 v=au(modn)。进行至多 t 次 v←v2 过程中进行二次探测。
通过所有二次探测后进行 Fermat 素性检验。
Miller Rabin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| inline ll qmul(ll a,ll b,ll m) { return (ull(a)*b-ull(ld(a)/m*b)*m+m)%m; } inline ll qpow(ll x,ll y,ll m) { ll r=1; for(;y;x=qmul(x,x,m),y/=2)if(y&1)r=qmul(r,x,m); return r; } constexpr ll A[7]={2,325,9375,28178,450775,9780504,1795265022};
inline bool MillerRabin(ll n) { if(n<3||n%2==0)return n==2; if(n%3==0)return n==3; ll u=n-1,t=0; while(u%2==0)u/=2,t++; for(int i=0;i<7;i++) { ll v=qpow(A[i]%n,u,n); if(v==0||v==1)continue; int s=0; for(;s<t;s++) { if(v==n-1)break; v=qmul(v,v,n); } if(s==t)return false; } return true; }
|
筛
埃氏筛
1 2 3 4 5 6 7 8
| std::vector<int> p; std::bitset<V> np; for(int i=2;i<=n;i++)if(!np[i]) { p.push_back(i); if(1ll*i*i>n)continue; for(int j=i*i;j<=n;j+=i)np[j]=true; }
|
线性筛
1 2 3 4 5 6 7 8 9 10 11 12
| std::vector<int> p; std::bitset<A> np; for(int i=2;i<=n;i++) { if(!np[i])p.push_back(i); for(int j:p) { if(1ll*i*j>n)break; np[i*j]=true; if(i%j==0)break; } }
|
爱用哪个用哪个。级别在 108 以下时埃氏筛可能有常数优势,109 时线性筛更快。
欧几里得算法
若 p=kq+r,则 r=pmodq,k=⌊p/q⌋。
设 a>b,g=gcd(a,b),则 g∣a,g∣b,即 g∣(a−kb),g∣amodb。
可得 gcd(a,b)=gcd(b,a−b)=gcd(b,amodb)。
1
| template<typename T> inline T gcd(T a,T b){return b?gcd(b,a%b):a;}
|
裴蜀定理
∃x,y∈Z,ax+by=gcd(a,b)。
显然可以在欧几里得算法过程中构造。
设 a=kb+r,gcd(a,b)=bx+ry,则 gcd(a,b)=bx+(a−kb)y=ay+(x−ky)b。
即 x′=y,y′=x−ky。
exCRT
为了求解线性同余方程 ax≡b(modm),通过 exgcd 求解 gcd(a,m)=ax′+my′。
可得
agcd(a,m)x′b+mgcd(a,m)y′b=b
这样我们就解出了一个特解。发现若 x0 是一个解,那么 x0+kgcd(a,m)m 也是一个解。
agcd(a,m)x′b+km+mgcd(a,m)y′b−ka=b
即 x≡x0(modm/gcd(a,m))。
那么对于方程组
⎩⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎧a1x≡b1(modm1)a2x≡b2(modm2)⋮anx≡bn(modmn)
解得
⎩⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎧x≡x1(modm1′)x≡x2(modm2′)⋮x≡xn(modmn′)
然后每次合并两个方程。设 x=x1+m1′y1=x2+m2′y2,可得 m1′y1=x2−x1+m2′y2≡x2−x1(modm2′)。解得 y1≡y0(modm2′/gcd(m1′,m2′))。代回有 x=x1+m1′y1≡x1+m1′y0(modm1′m2′/gcd(m1′,m2′)=lcm(m1′,m2′))。
CRT
数论分块