整数分解费马方法

写在前面:

  这篇博客是我在[◹]对 算术基本定理 的研究 中的一部分

整数分解费马方法

整数分解废马方法

  • 整数分解费马方法

  整数分解费马方法与费马小定理无关

  原理:

    任何一个正整数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 }