• 试除法分解大整数


    写在前面:

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

    • 试除法分解大整数

      每次筛出一个素数p[i],看看其是否为要分解的正整数n的真因子

      如果是的话,就除去n中所有的p[i]

      是一种很朴素的尝试的思想,时间复杂度很大

    (注意,这张流程图是我的早期想法,和实际代码有点差别)

      两个关键步骤的实现

      筛出素数p[i]:[◹]三个线性筛法

      判断素数:[◹]Miller-Rabin算法

      代码实现的话,把主要步骤套进素数线性筛里面就好了

    代码如下:

    C++:

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 int const MAXN=100010,MAXM=10010;
     6 
     7 int n,preN,num=1;
     8 int ans1[MAXM],ans2[MAXM];
     9 
    10 int prime[MAXN],tot;
    11 bool notprime[MAXN];
    12 
    13 int ponyFE(int a,int b,int c)
    14 {
    15     int ans=1;
    16     a%=c;
    17     while(b!=0)
    18     {
    19         if(b&1) ans=(ans*a)%c;
    20         b>>=1;
    21         a=(a*a)%c;
    22     }
    23     return ans;
    24 }
    25 
    26 bool millerRabin(int x)
    27 {
    28     if(x==2) return 1;
    29     if(!(x&1)||x==1) return 0;
    30     
    31     bool pass;
    32     int d=x-1,m;
    33     while(!(d&1)) d>>=1;int tmp=d;
    34     for(int i=1;i<=10;++i)
    35     {
    36         d=tmp;pass=0;
    37         
    38         m=ponyFE(rand()%(x-2)+2,d,x);
    39         if(m==1) continue;
    40         else for(;d<x&&d>=0;m=(m*m)%x,d<<=1)
    41             if(m==x-1){pass=1;break;}
    42         
    43         if(!pass) return 0;
    44     }
    45     
    46     return 1;
    47 }
    48 
    49 int main(int argc,char *argv[],char *enc[]){
    50     
    51     scanf("%d",&n);
    52     preN=n;
    53     
    54     notprime[0]=1;
    55     notprime[1]=1;
    56     for(int i=2;i<=n;++i){ 
    57         if(!notprime[i])
    58         {
    59             prime[tot++]=i;
    60             
    61             if(n%i==0)
    62             {
    63                 ans1[num]=i;
    64                 while(n%i==0){
    65                     ++ans2[num];
    66                     n/=i;
    67                 }
    68                 ++num;
    69             }
    70             
    71             if(n==1) break;
    72             
    73             if(millerRabin(n)){
    74                 ans1[num]=n;
    75                 ans2[num]=1;
    76                 ++num;
    77                 break;
    78             }
    79         }
    80         for(int j=0; j<tot && i*prime[j]<=n;++j){ 
    81             notprime[i*prime[j]]=1; 
    82             if(i%prime[j]==0) break;
    83         }
    84     }
    85     
    86     printf("%d==",preN);
    87     for(int i=1;i<num-1;++i)
    88         printf("%d^%d*",ans1[i],ans2[i]);
    89     printf("%d^%d
    ",ans1[num-1],ans2[num-1]);
    90     
    91     return 0;
    92 }

    Java:

     1 import java.util.Scanner;
     2 
     3 class Pony{
     4     
     5     static int MAXN=100010,MAXM=10010;
     6 
     7     static int n,preN,num=1;
     8     static int[] ans1=new int[MAXM];
     9     static int[] ans2=new int[MAXM];
    10 
    11     static int tot;
    12     static int[] prime=new int[MAXN];
    13     static boolean[] notprime=new boolean[MAXN];
    14 
    15     static int ponyFE(int a,int b,int c)
    16     {
    17         int ans=1;
    18         a%=c;
    19         while(b!=0)
    20         {
    21             if((b&1)==1) ans=(ans*a)%c;
    22             b>>=1;
    23             a=(a*a)%c;
    24         }
    25         return ans;
    26     }
    27 
    28     static boolean millerRabin(int x)
    29     {
    30         if(x==2) return true;
    31         if((x&1)==0||x==1) return false;
    32         
    33         boolean pass;
    34         int d=x-1,m;
    35         while((d&1)==0) d>>=1;int tmp=d;
    36         for(int i=1;i<=10;++i)
    37         {
    38             d=tmp;pass=false;
    39 
    40             m=ponyFE((int)(Math.random())%(x-2)+2,d,x);
    41             if(m==1) continue;
    42             else for(;d<x&&d>=0;m=(m*m)%x,d<<=1)
    43                 if(m==x-1){pass=true;break;}
    44         
    45             if(!pass) return false;
    46         }
    47         
    48         return true;
    49     }
    50 
    51     public static void main(String[] args) throws Exception
    52     {
    53         Scanner cin=new Scanner(System.in);
    54 
    55         n=cin.nextInt();
    56         preN=n;
    57         
    58         notprime[0]=true;
    59         notprime[1]=true;
    60         for(int i=2;i<=n;++i){ 
    61             if(!notprime[i])
    62             {
    63                 prime[tot++]=i;
    64                 
    65                 if(n%i==0)
    66                 {
    67                     ans1[num]=i;
    68                     while(n%i==0){
    69                         ++ans2[num];
    70                         n/=i;
    71                     }
    72                     ++num;
    73                 }
    74                 
    75                 if(n==1) break;
    76                 
    77                 if(millerRabin(n)){
    78                     ans1[num]=n;
    79                     ans2[num]=1;
    80                     ++num;
    81                     break;
    82                 }
    83             }
    84             for(int j=0; j<tot && i*prime[j]<=n;++j){ 
    85                 notprime[i*prime[j]]=true; 
    86                 if(i%prime[j]==0) break;
    87             }
    88         }
    89 
    90         System.out.printf("%d==",preN);
    91         for(int i=1;i<num-1;++i)
    92             System.out.printf("%d^%d*",ans1[i],ans2[i]);
    93         System.out.printf("%d^%d
    ",ans1[num-1],ans2[num-1]);
    94     }
    95 }

  • 相关阅读:
    【cocos2d-js官方文档】十四、cc.spriteFrameCache 改造说明
    [SVN]创建本地的SVN仓库
    [C++]函数参数浅析
    [Windows Phone]AnimationHelper管理分散的Storyboard
    [Windows Phone]常用类库&API推荐
    [Windows Phone]模仿魔兽3技能按钮SkillButton
    [C++]引用浅析
    [C++]new和delete
    [C++]指针浅析
    [C++]C++中的运行时类型检测
  • 原文地址:https://www.cnblogs.com/Antigonae/p/10247634.html
Copyright © 2020-2023  润新知