zoukankan      html  css  js  c++  java
  • 欧拉降幂

     

    处理何种问题:在处理 a^b mod c 的问题中,如果遇到b的值极大,大到只能用字符串来存取时,普通的快速幂已经无法处理该问题时,就该用到欧拉降幂来处理了。

     

    性能:可以将时间复杂度降至快速幂的水平。

     

    原理:  a^b mod c  == a^(b mod phi(c)+phi(c)) mod c 

     (PS: phi(x) 为欧拉函数);其核心就是将大数 b 降至为一个long long 级别的数。

     

    实现步骤:在计算 时的处理方式

    int len=strlen(b);

    long long ola=PHI(mod); // phi(c) 的值为ola

    long long n=0;

    for(int i=0;i<len;++i)

    {

        n=(n*10+b[i]-'0')%ola;

    }

     

    备注:若题目中给的出的b需要处理一下才是才行,比如给出一个b,但是需要求的是(b-1)的时候,在这里并不需要再加一个大数减法,只需要用加个减法取模就行了。

     

    输入样例解释

    2 3 10007 // a的b次方对c取模

    5 15555555555555555555555555555555 2666

    5555 9999999999999999999999999999999999999999999999999 100005

     

    输出样例解释

    8

    1427

    79370

    //没文化真可怕,一个n的10的100000次方的次方天真的要用大数加快速幂去做,天真
    //。。。。现在终于知道了,这就是超级快速幂,遇到这种题,需要用到欧拉降幂,。。。无知的我
    //公式:a^b mod c  == a^(b mod phi(c)+phi(c)) mod c   (phi 为 欧拉函数)
    //这种题目一般比较适合 b 特别大的情况下,大到 b 只能用字符串来存取了
    
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<cmath>
    #include<cstdio>
    using namespace std;
    
    const int MaxN=1000100;
    
    
    long long  fpow(long long  a,long long n,long long  mod)
    {
        long long Ans=1;
        a=a%mod;
        while(n!=0)
        {
            if(n&1)
                Ans=(Ans*a)%mod;
            n>>=1;
            a=(a*a)%mod;
        }
        return Ans;
    }
    
    long long  PHI(long long  x)
    {
        long long ans = x;
        for(long long i = 2; i*i <= x; i++)
        {
            if(x % i == 0)
            {
                ans = ans / i * (i-1);
                while(x % i == 0) x /= i;
            }
        }
        if(x > 1) ans = ans / x * (x-1);
        return ans;
    }
    
    long long o_fpow(long long a,char b[],long long mod)
    {
        int len=strlen(b);
        long long ola=PHI(mod);
        long long n=0;
        for(int i=0;i<len;++i)
        {
            n=(n*10+b[i]-'0')%ola;
        }
        n+=ola;
        return fpow(a,n,mod);
    }
    
    
    int main()
    {
        long long a,mod;
        char b[MaxN];
        while(~scanf("%lld%s%lld",&a,b,&mod))// a 的 b 次方对mod取模
        {
            printf("%lld
    ",o_fpow(a,b,mod));
        }
        return 0;
    }
  • 相关阅读:
    CMD常用命令
    SpringMVC常用方法总结
    Oracle数据库中,sql中(+)(-)的含义
    电脑配置Java环境变量之后,在cmd中仍然无法识别
    tomcat部署项目遇到的问题
    tomcat的stratup小黑框名字修改
    CSS定位
    cookie存储userID所遇到的问题
    修改Tomcat的server.xml之后,tomcat 部署项目报错:Removing obsolete files from server... Could not clean server of obsolete files: null java.lang.NullPointerException
    安装oracle11g跳不过下载软件更新[INS-30131] 执行安装程序验证所需的初始设置失败
  • 原文地址:https://www.cnblogs.com/l1l1/p/9658131.html
Copyright © 2011-2022 走看看