@@ -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