@@ -67,7 +67,79 @@ void segment_sieve(LL a,LL b)//[a,b]
67
67
}
68
68
}
69
69
```
70
+ #大素数分解与大素数测试
70
71
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
+ ```
71
143
#euler phi函数
72
144
$\phi(n) = n\prod_{i = 1}^{k}(1-\frac{1}{p_i})$
73
145
证明详见《初等数论及其应用》
0 commit comments