zoukankan      html  css  js  c++  java
  • 2019ICPC南京网络赛B super_log

    题意:求a的a的a次方。。一直求b次,也就是在纸上写个a,然后一直a次方a次方,对m取模,记为F(a,b,m)=pow(a,F(a,b-1,phi(m))

    解题思路:联系欧拉降幂,这个迭代的过程,我们是一直对m求欧拉函数,然后在对这个结果求欧拉函数,显然这个过程迭代次数不会多,验证可得1e6范围内最多迭代19次,

    但是这个题有个坑,快速幂必须取mod后+mod,才不会出现结果为0的情况,为0会导致有些情况不对(wa)

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+5;
    typedef long long ll;
    bitset<maxn>notprime;
    int phi[maxn],prime[maxn],cnt=0;
    void pre(){
        phi[1]=1;
        for(int i=2;i<=maxn-5;i++){
            if(!notprime[i]){
                prime[++cnt]=i;
                phi[i]=i-1;//i为素数时,phi[i]=i-1
            }
            for(int j=1;j<=cnt&&prime[j]*i<=maxn;j++){
                notprime[i*prime[j]]=1;
                if(i%prime[j]==0){//每个数只被它的最小质因数给筛掉
                    phi[i*prime[j]]=phi[i]*prime[j];
                    //当a与b互质时,满足phi(a∗b)=phi(a)∗phi(b),积性函数
                    break;
                }
                else phi[i*prime[j]]=phi[i]*(prime[j]-1);
                //phi[i∗prime[j]]=phi[i]∗phi[prime[j]]=phi[i]∗(prime[j]−1);
            }
        }
    }
    ll quick_mod(ll a,ll n,ll mod)
    {
        ll res=1;
        while (n)
        {
            if(n&1)res=res*a>mod?res*a%mod+mod:res*a;
            a=a*a>mod?a*a%mod+mod:a*a;
            n>>=1;
        }
        return res;
    }
    ll deal(ll a,ll b,ll m)
    {
        if(b==0)return 1;
        if(m==1)return 1;
        ll res=deal(a,b-1,phi[m]);
        return quick_mod(a,res,m);
    }
    int main(){
        pre();
        int t;
        cin>>t;
        ll a,b,m;
        while (t--)
        {
            cin>>a>>b>>m;
            cout<<deal(a,b,m)%m<<endl;
        }
    }
  • 相关阅读:
    加一
    斐波那契数
    整数的各位积和之差
    移除元素
    删除排序数组中的重复项
    有效的括号
    爬楼梯
    最长公共前缀
    罗马数字转整数
    回文数
  • 原文地址:https://www.cnblogs.com/xusirui/p/11443214.html
Copyright © 2011-2022 走看看