整数分解费马方法
写在前面:
这篇博客是我在[◹]对 算术基本定理 的研究 中的一部分
整数分解废马方法
-
整数分解费马方法
整数分解费马方法与费马小定理无关
原理:
任何一个正整数n都能拆成n==2k*a的形式,其中a为一个奇数
我们在a上搞事情:
若a==c*d (c>d,且显然cd都是奇数)
那么让x==(c+d)/2,让y==(c-d)/2
这里是逻辑上的证明,并不是计算机要实现的内容,根本不考虑丢精的情况(就算考虑了,cd都是奇数,不会丢精)
那么x2-y2==(c2+d2+2c*d)/4-(c2+d2-2c*d)/4==(4c*d)/4==c*d==a
枚举x2,看看x2-a是不是完全平方数
如果是的话,那么c==x+√(x2-a)和d==x-√(x2-a)就都是a的因子
可以枚举x2,找出a的所有因子!
有用的性质:
接着上面的证明,x==(c+d)/2,a==c*d
根据基本不等式,(c+d)/2 >= √(cd)
即x2 >= a
在枚举时x2 >= a时才有解
代码如下:
C++:
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 int n; 6 int tmp; 7 8 int ponySqrt(int x){ 9 if(x<=0) return -1; 10 return (int)sqrt(x)*(int)sqrt(x)==x? (int)sqrt(x):-1; 11 } 12 13 int main(int argc,char *argv[],char *enc[]) 14 { 15 scanf("%d",&n); 16 17 printf("%d==1",n); 18 19 while(n%2==0){ 20 n/=2; 21 printf("*2"); 22 } 23 24 for(int i=(int)sqrt(n);;++i){ 25 tmp=ponySqrt(i*i-n); 26 if(tmp!=-1){ 27 printf("*%d*%d",i+tmp,i-tmp); 28 n/=(i+tmp); 29 n/=(i-tmp); 30 if(n<=1) break; 31 i=(int)sqrt(n); 32 } 33 } 34 return 0; 35 }
Java:
1 import java.util.Scanner; 2 import java.lang.Math; 3 4 class Pony{ 5 6 static int n,tmp; 7 8 static int ponySqrt(int x){ 9 if(x<=0) return -1; 10 return (int)Math.sqrt(x)*(int)Math.sqrt(x)==x? (int)Math.sqrt(x):-1; 11 } 12 13 public static void main(String[] args) throws Exception 14 { 15 Scanner cin=new Scanner(System.in); 16 17 n=cin.nextInt(); 18 19 System.out.printf("%d==1",n); 20 21 while(n%2==0){ 22 n/=2; 23 System.out.printf("*2"); 24 } 25 26 for(int i=(int)Math.sqrt(n);;++i){ 27 tmp=ponySqrt(i*i-n); 28 if(tmp!=-1){ 29 System.out.printf("*%d*%d",i+tmp,i-tmp); 30 n/=(i+tmp); 31 n/=(i-tmp); 32 if(n<=1) break; 33 i=(int)Math.sqrt(n); 34 } 35 } 36 } 37 }