• ACM 数论模板(整理)


    本文地址:

    http://www.cnblogs.com/Lee-geeker/p/3372084.html

    转载请注明。

    1.最大公约数和最小公倍数。

    //模版
    int gcd(int a, int b)
    {
        if(a<b){int t=a;a=b;b=t;}
        return a%b==0?b:gcd(b,a%b);
    }
    int lcm(int a, int b)
    {
        return a/gcd(a,b)*b;
    }

     参考题目:HDU1018  http://acm.hdu.edu.cn/showproblem.php?pid=1108

    #include<iostream>
    
    using namespace std;
    
    int gcd(int a, int b){    if(a<b){int t=a;a=b;b=t;}    return a%b==0?b:gcd(b,a%b);}
    int lcm(int a, int b){    return a/gcd(a,b)*b;}
    
    int main()
    {
        int a,b;
        while(scanf("%d%d",&a,&b)!=EOF)
        {
            printf("%d
    ",lcm(a,b));
        }
        return 0;
    }
    View Code
    2.快速幂取模( Montgomery算法)
    __int64 qpow(int a,int b,int r)//快速幂 
    {
        __int64 ans=1,buff=a;
        while(b)
        {
            if(b&1)ans=(ans*buff)%r;
            buff=(buff*buff)%r;
            b>>=1;
        }
        return ans;
    }

    可参考题目:HDU1395  http://acm.hdu.edu.cn/showproblem.php?pid=1395

    #include<iostream>
    
    using namespace std;
    
    unsigned Montgomery(unsigned n,unsigned p,unsigned m)
    { //快速计算(n^e)%m的值
          unsigned k=1;
          n%=m;
         while(p!=1)
         {
             if(0!=(p&1))k=(k*n)%m;
             n=(n*n)%m;
             p>>=1;
        }
        return(n*k)%m;
    }
    int main()
    {
        int n;
        int flag,i;
        while(scanf("%d",&n)!=EOF)
        {
            if(!(n&1)||n<=1)
                printf("2^? mod %d = 1
    ",n);
            else
                for(i=1;;i++)
                {
                    if(Montgomery(2,i,n) == 1)
                    {
                        printf("2^%d mod %d = 1
    ",i,n);
                        break;
                    }
                }
        }
        return 0;
    }
    View Code

     可参考题目:HDU2035 http://acm.hdu.edu.cn/showproblem.php?pid=2035

    #include<iostream>
    
    using namespace std;
    
    __int64 qpow(int a, int p, int r)
    {
        int ans = 1;
        int buff = a;
        while(p)
        {
            if(p&1)    ans = (ans*buff)%r;
            buff = buff*buff%r;
            p>>=1;
        }
        return ans;
    }
    
    int main()
    {
        int a,b;
        while(scanf("%d%d",&a,&b)!=EOF&&(a!=0&&b!=0))
        {
            printf("%d
    ",qpow(a,b,1000));
        }
        return 0;
    }
    View Code
    #include <iostream>
    using namespace std;
    int main()
    {
        int a,b,ans;
        while(cin>>a>>b)
        {
            if(!a && !b)
                break;
            ans=0;
            a=a%1000;
            int tmp=a;
            while(b-->1)
            {
                a=(a*tmp)%1000;
            }
            cout<<a<<endl;
        }
        return 0;
    }
    View Code
    3.费马小定理
    //费马小定理是数论中的一个重要定理,其内容为: 假如p是质数,且(a,p)=1,那么 a^(p-1) ≡1(mod p)。即:假如p是质数,且a,p互质,那么a的(p-1)次方除以p的余数恒等于1。
    4196 4704
    4.找规律,循环结问题,递推
    1005 1021 2050 1719
    5.同余式,中国剩余定理
    3430 1573

    6.米勒拉宾素数测试

    __int64 qpow(int a, int b, int r)
    {
        __int64 ans=1, buffer=a;
        while(b)
        {
            if(b&1) ans = ans*buffer%r;
            buffer = buffer*buffer%r;
            b>>=1;
        }
        return ans;
    }
    bool Miller_Rabbin(int n, int a)
    {
        int r=0,s=n-1,j;
        if(!(n%a))
            return false;
        while(!(s&1))
        {
            s>>=1;
            r++;
        }
        __int64 k=qpow(a,s,n);
        if(k==1)
            return true;
        for(j=0;j<r;j++,k=k*k%n)
        {
            if(k==n-1)
                    return true;        
        }
        return false;
    }
    
    bool IsPrime(int n)
    {
        int tab[]={2,3,5,7,11};
        for(int i=0;i<5;i++)
        {
            if(n==tab[i])
                return true;
            if(!Miller_Rabbin(n,tab[i]))
                return false;    
        }
        return true;
    }

    参考:HDOJ2138   http://acm.hdu.edu.cn/showproblem.php?pid=2138

    #include<iostream>
    
    
    using namespace std;
    
    
    __int64 qpow(int a, int b, int r)
    {
        __int64 ans=1, buffer=a;
        while(b)
        {
            if(b&1) ans = ans*buffer%r;
            buffer = buffer*buffer%r;
            b>>=1;
        }
        return ans;
    }
    bool Miller_Rabbin(int n, int a)
    {
        int r=0,s=n-1,j;
        if(!(n%a))
            return false;
        while(!(s&1))
        {
            s>>=1;
            r++;
        }
        __int64 k=qpow(a,s,n);
        if(k==1)
            return true;
        for(j=0;j<r;j++,k=k*k%n)
        {
            if(k==n-1)
                    return true;        
        }
        return false;
    }
    
    bool IsPrime(int n)
    {
        int tab[]={2,3,5,7,11,13};
        for(int i=0;i<6;i++)
        {
            if(n==tab[i])
                return true;
            if(!Miller_Rabbin(n,tab[i]))
                return false;    
        }
        return true;
    }
    
    int main()
    {
        int i,N;
        long tmp, count;
        while(scanf("%d",&N)!=EOF)
        {
            count = 0;
            for(i=0;i<N;i++)
            {
                scanf("%ld",&tmp);
                if(IsPrime(tmp))
                    count++;
            }
            printf("%d
    ",count);
        }
    }
    View Code
    7.筛选法
    
    1999 1286 2098
    8.素数的筛选法,穷举,因数,判定等

    #include<iostream>
    
    using namespace std;
    
    bool prime[10000+5];
    
    void Init()
    {
        for(int i = 2; i <= 10000; ++i)
        {
            prime[i] = true;
        }
        for(int i =2;i <= 10000; ++i)
        {
            if(prime[i] == true)
            {
                for(int j = 2; i*j <= 10000; ++j)
                    prime[i*j] = false;
            }
        }
    }
    //保存素数
    #include<iostream>
    #include<string.h>
    using namespace std;
    
    #define N 100001
    bool IsPrime[N];
    int Prime[N],cnt;
    
    void Init_Prime_Table()
    {
        long long int i,j;//注意,i比较大时会容易超int的范围。
         
        cnt = 0;
        memset(IsPrime,true,sizeof(IsPrime));
        IsPrime[1] = false;
        for(i=2;i<=N;i++)
        {
            if(IsPrime[i])
            {
                Prime[cnt++] = i;
                for(j=i*i;j<=N;j+=i)
                    IsPrime[j] = false;
            }
        }
    }
    
    
    int main()
    {
        Init_Prime_Table();
        for(int i=0;i<1000;i++)
        {
            printf("%5d",Prime[i]);
        } 
        
        return 0;
    }


    2098 2161

    9
    .普通素数判定
    bool IsPrime(int n)
    {
        int i = 0;
        if(n<=2) return false;
        for(i=2;i*i<=n;i++)
        {
            if(n%i==0)
                return false;
        }
        return true;
    }


  • 相关阅读:
    CentOS6.4 安装OpenResty和Redis 并在Nginx中利用lua简单读取Redis数据
    nginx缓存批量清除
    Centos下Yum安装PHP5.5,5.6
    php中的脚本加速扩展opcache
    Centos 6.5 挂载硬盘 4K对齐 (笔记 实测)
    centos6.5下编译安装FFmpeg
    Python学习九:列表生成式
    Python Select 解析
    Python之基于socket和select模块实现IO多路复用
    Python之路,Day9 , IO多路复用(番外篇)
  • 原文地址:https://www.cnblogs.com/Lee-geeker/p/3372084.html
Copyright © 2020-2023  润新知