大数分解模板

  1 program j01;
  2 const times=50;
  3 var n:int64;
  4     fac:array[0..6000]of int64;
  5     num:array[0..6000]of record w,m:int64;end;
  6     ans:int64;
  7     i,cnt,top:longint;
  8  
  9 procedure sort(l,r:longint);
 10 var i,j:longint;x,y:int64;
 11 begin
 12   i:=l;j:=r;x:=fac[(i+j)div 2];
 13   repeat
 14     while fac[i]<x do inc(i);
 15     while x<fac[j] do dec(j);
 16     if i<=j then
 17     begin
 18       y:=fac[i];fac[i]:=fac[j];fac[j]:=y;
 19       inc(i);dec(j);
 20     end;
 21   until i>j;
 22   if i<r then sort(i,r);
 23   if l<j then sort(l,j);
 24 end;
 25  
 26 function mul(a,b,mo:int64):int64;
 27 begin
 28   mul:=0;
 29   while b>0 do
 30   begin
 31     if b and 1=1 then mul:=(mul+a)mod mo;
 32     b:=b>>1;a:=(a+a)mod mo;
 33   end;
 34 end;
 35  
 36 function pow(a,i,mo:int64):int64;
 37 begin
 38   pow:=1;
 39   while i>0 do
 40   begin
 41     if i and 1=1 then pow:=mul(pow,a,mo);
 42     i:=i>>1;a:=mul(a,a,mo);
 43   end;
 44 end;
 45  
 46 function miller_rabin(n:int64):boolean;
 47 var i,j:longint;a,x,y,m,k:int64;
 48 begin
 49   if n=2 then exit(true);
 50   m:=n-1;k:=0;
 51   while m and 1=0 do
 52   begin
 53     m:=m>>1;inc(k);
 54   end;
 55   for i:=1 to times do
 56   begin
 57     a:=random(n-1)+1;
 58     x:=pow(a,m,n);y:=0;
 59     for j:=1 to k do
 60     begin
 61       y:=mul(x,x,n);
 62       if(y=1)and(x<>1)and(x<>n-1)then exit(false);
 63       x:=y;
 64     end;
 65     if y<>1 then exit(false);
 66   end;
 67   exit(true);
 68 end;
 69  
 70 function gcd(a,b:int64):int64;
 71 begin
 72   if b=0 then exit(a) else exit(gcd(b,a mod b));
 73 end;
 74  
 75 function rho(n,c:int64):int64;
 76 var i,k,x,y,tmp,d:int64;
 77 begin
 78   i:=1;k:=2;
 79   x:=random(n-1)+1;y:=x;
 80   while true do
 81   begin
 82     inc(i);
 83     x:=(mul(x,x,n)+c)mod n;
 84     tmp:=(y-x+n)mod n;
 85     d:=gcd(tmp,n);
 86     if(d>1)and(d<n)then exit(d);
 87     if y=x then exit(n);
 88     if i=k then
 89     begin
 90       k:=k+k;y:=x;
 91     end;
 92   end;
 93 end;
 94  
 95 procedure find(n:int64);
 96 var p:int64;
 97 begin
 98   if n=1 then exit;
 99   if miller_rabin(n) then
100   begin
101     inc(cnt);fac[cnt]:=n;exit;
102   end;
103   p:=n;
104   while p>=n do p:=rho(p,random(n-1)+1);
105   find(p);find(n div p);
106 end;
107  
108 begin
109   readln(n);
110   if n=1 then begin writeln(1);halt;end; 
111   find(n);
112   sort(1,cnt);
113   top:=1;num[top].w:=fac[1];num[top].m:=1;
114   for i:=2 to cnt do
115     if fac[i]=fac[i-1] then inc(num[top].m) else
116     begin
117       inc(top);num[top].w:=fac[i];num[top].m:=1;
118     end;
119   for i:=1 to top do writeln(num[i].w,' ',num[i].m);
120 end.

 

posted @ 2017-04-04 13:14  OldJang  阅读(540)  评论(1编辑  收藏  举报