Skip to content

Commit 12d871a

Browse files
author
taotao
committed
添加miller rabin测试和pollard_pro方法
1 parent 09af8a3 commit 12d871a

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed

Diff for: math/数论算法模板总结.md

+72
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,79 @@ void segment_sieve(LL a,LL b)//[a,b]
6767
}
6868
}
6969
```
70+
#大素数分解与大素数测试
7071

72+
##miller_rabin
73+
74+
已知最快的素数分解算法.$O(lgV)$
75+
76+
```c++
77+
bool witness(LL a,LL n,LL u,LL t){
78+
LL x0 = power_mod(a,u,n),x1;
79+
for(int i=1 ;i<=t ; ++i){
80+
x1 = mulmod(x0,x0,n);
81+
if(x1==1 && x0!=1 && x0!=n-1)
82+
return false;
83+
x0 = x1;
84+
}
85+
if(x1 !=1)return false;
86+
return true;
87+
}
88+
89+
bool miller_rabin(LL n, int times = 20){
90+
if(n<2)return false;
91+
if(n==2)return true;
92+
if(!(n&1))return false;
93+
LL u = n-1,t =0;
94+
while (u%2==0) {
95+
t++;u>>=1;
96+
}
97+
while (times--) {
98+
LL a = random(1,n-1);
99+
//if(a == 0)std::cout << a << " "<<n<< " "<<u<<" " << t<<'\n';
100+
if(!witness(a,n,u,t))return false;
101+
}
102+
return true;
103+
}
104+
```
105+
106+
##pollard_rho
107+
分解一个合数$V$的运行时间$O(V^{1/4 })$
108+
```c++
109+
/*
110+
*pollard_rho分解n,
111+
*c : 随机迭代器,每次运行设置为随机种子往往更快.
112+
*/
113+
LL pollard_rho(LL n,LL c = 1){
114+
LL x = random(1,n);
115+
LL i =1,k =2,y = x;
116+
while (1) {
117+
i++;
118+
x = (mulmod(x,x,n)+c)%n;
119+
LL d = gcd(y-x>=0?y-x:x-y,n);
120+
if(d!=1 && d!=n)return d;//非平凡因子.
121+
if(y==x)return n;//重复.
122+
if(i==k){ y = x ; k<<=1;}//将x_1,2,4,8,16,..赋值为y.
123+
}
124+
}
125+
```
126+
* 找出因子分解
127+
$O(V^{1/4}lgV)$
128+
```c++
129+
void find_factor(LL n,std::map<LL, int> & m){
130+
if(n<=1)return ;
131+
if(miller_rabin(n)){
132+
++m[n];
133+
return ;
134+
}
135+
LL p = n;
136+
137+
while (p==n)p = pollard_rho(p,random(1,n));
138+
find_factor(p,m);
139+
find_factor(n/p,m);
140+
}
141+
142+
```
71143
#euler phi函数
72144
$\phi(n) = n\prod_{i = 1}^{k}(1-\frac{1}{p_i})$
73145
证明详见《初等数论及其应用》

0 commit comments

Comments
 (0)