zoukankan      html  css  js  c++  java
  • ACM一道关于素数查找的题

    在ACM做这么一道题:


    我用了最简单的查找素数的方法:

    bool isPrime(int n)
    {
    	int t=n-1;
    	
    	while(t>2)
    	{
    		if(n%t==0)
    		{
    			return false;
    		}
    		t--;
    	}
    	return true;
    }
    结果正确,却超时了,后来发现当变量是一个大数的时候这种查找效率极低,于是就在网站各种搜索快速的判断素数的算法

    Miller Rabin算法:

    typedef unsigned __int64 llong; 
    
    llong mod_pro(llong x,llong y,llong n) 
    { 
        llong ret=0,tmp=x%n; 
        while(y) 
        { 
            if(y&0x1)if((ret+=tmp)>n)ret-=n; 
            if((tmp<<=1)>n)tmp-=n; 
            y>>=1; 
        } 
        return ret; 
    } 
    llong mod(llong a,llong b,llong c) 
    { 
        llong ret=1; 
        while(b) 
        { 
            if(b&0x1)ret=mod_pro(ret,a,c); 
            a=mod_pro(a,a,c); 
            b>>=1; 
        } 
        return ret; 
    } 
    llong ran() 
    { 
        llong ret=rand(); 
        return ret*rand(); 
    } 
    bool isPrime2(llong n) 
    { 
    	int t=2;
        if(n<2)return false; 
        if(n==2)return true; 
        if(!(n&0x1))return false; 
        llong k=0,m,a,i; 
        for(m=n-1;!(m&1);m>>=1,k++); 
        while(t--) 
        { 
            a=mod(ran()%(n-2)+2,m,n); 
            if(a!=1) 
            { 
                for(i=0;i<k&&a!=n-1;i++) 
                    a=mod_pro(a,a,n); 
                
                if(i>=k)return false; 
            } 
        } 
        return true; 
    } 
    对比一下速度:

    我的

    Miller Rabin算法:




  • 相关阅读:
    学习进度笔记13
    学习进度笔记12
    学习进度笔记11
    学习进度笔记10
    学习进度笔记9
    《架构之美》读书笔记1
    学习进度笔记8
    电话拨号盘(带触摸振动反馈)
    堆排序(小根堆)
    图论起步(长期更新)
  • 原文地址:https://www.cnblogs.com/hisheng/p/6134974.html
Copyright © 2011-2022 走看看