Article changes will not be pinned to look really uncomfortable ...
⑤miller-rabin
Kee N-1=a*2^b. Select an integer x randomly in [1,n], if x^a≡1 or x^ (a*2^i) ≡-1 (where 0<=i<b), then we think N is prime.
The correct rate is probably ((1/4) ^ random number of times)
⑥pollard-rho
A more face-looking algorithm ...
We first define a function f (x) = (x^2+1)%n. So if I keep calling F (x), F (f (x)), F (f (f (x))) ... Then you can generate a random number sequence, right.
Pollard_rho is an algorithm that can accept a number n and return one of its factors. The algorithm flow is this, starting with a x[1], in [0,n] inside the random, we make x[i]=f (X[i-1]).
Each time we calculate gcd (x[k]-x[2k],n), if we return n, the decomposition fails and we need to regenerate a x[1]. If you return 1, continue to add K plus 1. Otherwise, we'll find a factor of N.
When implemented, it is important to note that because of the nature of this random function f, when n is a multiple of 2, it is better to be very specific, otherwise it may seem to be a dead loop.
Let's calculate the complexity, this complexity looks more metaphysical, it can find a small factor p of N in the time complexity of O (sqrt (p)), so the complexity is almost O () (because there is also a gcd and a fast multiply (because the data range problem is usually used when calculating f)).
If you want to decompose the factorization, the complexity is almost O () ... In fact, to write Miller-rabin ah, fast multiplication ah, memory allocation Ah, constant is very big ...
Example 4 factors and
Give a larger number n, and the all factors of N. There are multiple sets of data.
T<=50,n<=10^18.
This is a pollard-rho naked question. How long do you think Pollard-rho will run? 0.1s?
This is the case, so the constant of the pollard-rho is usually to pay attention to ...
This code uses a vector, but the number of qualitative factors will not exceed 60, it should not be a big problem to save
#include <iostream>#include<stdio.h>#include<stdlib.h>#include<algorithm>#include<string.h>#include<vector>#include<math.h>#include<limits>#include<Set>#include<map>using namespaceStd;typedefLong LongLl;ll C_f (ll a,ll b,ll c) {if(b==0)return 0; LL HF=c_f (a,b>>1, c); HF= (HF+HF)%C; if(b&1) hf= (hf+a)%C; returnHF;} ll CF (ll A,ll b,ll c) {a%=c; b%=C; if(!a| |! breturn 0; if(a<0&&b<0) a=-a,b=-b; if(b<0)returnC-c_f (a,-b,c); if(a<0)returnC-c_f (-a,b,c); returnC_f (a,b,c);} ll QP (ll x,ll y,ll m) {if(y==0)return 1; LL HF=QP (x,y>>1, M); HF=CF (HF,HF,M); if(y&1) HF=CF (hf,x%m,m); returnHF;}BOOLIsPrime (ll p) {intb=0; ll a=p-1; while(! (a&1)) ++b, a>>=1; for(intI=1; i<=Ten; i++) {ll x=rand ()% (p1)+1; if(QP (x,a,p) = =1)GotoCT; for(intj=0; j<b;j++) { if(QP (x,a* (1<<J), p) ==p-1)GotoCT; } return 0; CT:; } return 1;} ll F (ll X,ll p) {return(cf (X%P,X%P,P) +1)%p;} ll GCD (ll A,ll b) {if(a<0) a=-A; if(b<0) b=-b; while(b) {ll g=a%b; a=b; b=G;} returnA;} ll Pollard_rho (ll m) {if(m==1)return 1; if(m%2==0)return 2; if(m%3==0)return 3; if(IsPrime (m))returnm; S:ll x=rand ()%m,y=f (x,m), p=1; while(p==1) {x=f (x,m); Y=f (f (y,m), m); P=GCD (xy,m); } if(p==m)Gotos; returnp;}#defineVll vector<ll>vll Merge (Vll A,vll b) {vll ans; int as=0, bs=0; while( as<a.size ()) Ans.push_back (a[ as++]); while(Bs<b.size ()) Ans.push_back (b[bs++]); returnans;} Vll Ysh (ll x) {if(x==1) {returnvll ();} if(IsPrime (x)) {vll ans; ans.push_back (x);returnans;} ll Ys; Vll ans; while((Ys=pollard_rho (x))! =1) {VLL cur=Ysh (YS); while(x%ys==0) X/=ys, ans=merge (Ans,cur); } returnans;} ll Calc (Vll x) {sort (X.begin (), X.end ()); intn=x.size (); ll SS=1; for(intI=0; i<n;i++) {ll cur=X[i]; inttot; for(intj=i;j<n;j++) { if(x[j]!=cur) Break; Tot=J; } intcnt=tot-i+1; ll Sum=1, sp=1; for(intI=1; i<=cnt;i++) Sp=sp*cur, sum+=sp; SS*=sum; I=tot; } returnSS;}intMain () {intT; ll x; scanf ("%d",&T); while(t--) {scanf ("%lld",&x); printf ("%lld\n", Calc (Ysh (x))); }}
⑦ Chinese remainder theorem
Normal version:
Give a number of n prime numbers/coprime, give you an x divided by these numbers to get the remainder, to find the smallest x.
For example, ask for an X to make x mod 3=2,x mod 5=3,x mod 7=5.
We first ask for a multiple of 5, 7 and mod 3=2 X, that is, 35p mod 3=2, this EXGCD solution. Then be realistic 3, 7 times times and MoD 5=3, then 5, 7 times times and MoD 3=2, and then add together can be satisfied with the conditions.
Then Ysy gave a magical formula:
Seems to be correct obviously.
Special version?
Example 5 solving equations
Give the n equations, each equation shaped like x mod Pi=ai, to find the smallest non-negative integer x satisfying the condition. No solution output-1.
n<=6,pi<=1000 (actually telling you the answer won't explode long long
We find that the conditions of coprime are gone, and there may be conflicting situations ...
For example, x mod 4=2,x mod 2=1 is contradictory.
Well, it seems as if we split each pi into a power of prime and then we can convert it into a normal version.
Is it good to write? (╯‵-′) ╯︵┻━┻ hard to write, okay?
What's the point of doing that?
We can combine these equations together!
Suppose we want to merge the X mod b1=n1,x mod b2=n2.
Set X=B1*K1+N1=B2*K2+N2, then b1*k1-b2*k2=n2-n1.
We can use the EXGCD to solve the K1 (notice the case of no solution), and then bring back x=x ', then we can combine two equations into X mod LCM (b1,b2) =x '.
Start making x mod 1=0.
#include <iostream>#include<stdio.h>#include<stdlib.h>#include<algorithm>#include<string.h>#include<vector>#include<math.h>#include<limits>#include<Set>#include<map>using namespaceStd;typedefLong Longll;intn;ll gcd (ll a,ll b) {if(a<0) a=-A; if(b<0) b=-b; while(b) {ll t=a%b; a=b; b=T;} returnA;}voidEX_GCD (ll a,ll b,ll& x,ll&y) { if(!B) {x=1; y=0;return;} EX_GCD (B,a%b,x,y); ll Y_=x-a/b*y; X=y; y=Y_;} ll EXGCD (ll a,ll b,ll c) {ll GG=gcd (A, b); if(C%GG)return-2333; A/=gg; B/=gg; C/=GG; ll x, y; EX_GCD (A,b,x,y); X=x*c; X%=b; y= (c-x*a)/b; returnx;} ll LCM (ll A,ll b) {returnA/GCD (A, b) *b;}intMain () {ll x=1, y=0, G,h; scanf ("%d",&N); for(intI=1; i<=n;i++) {scanf ("%lld%lld",&g,&h); Long LongP=EXGCD (x,g,h-y); if(p==-2333) {puts ("-1");return 0;} Long Longx=p*x+y; Long LongLc=LCM (X,G); Y= (X%LC+LC)%LC; x=LC; } printf ("%lld\n", y);}
Fundamentals of Number Theory 2