zoukankan      html  css  js  c++  java
  • HDU2837 Calculation(指数循环节)题解

    题意:

    已知(f(0)=1,f(n)=(n\%10)^{f(n/10)}),求(f(n)mod m)

    思路:

    由扩展欧拉定理可知:当(b>=m)时,(a^bequiv a^{b\%varphi(m)+varphi(m)}mod m),那么我们可以通过这个式子直接去递归求解。
    在递归的时候每次给下一个的模数都是(phi(mod)),那么我们求出来之后,怎么知道要不要再加(phi(m))
    我们可以在每次返回的时候用一个特殊的快速幂返回正确的值。然后每次特判返回值的时候都要一样:

    a = mod? a % mod + mod : a

    ll ksm(ll a, ll b, ll mod){
        ll ret = 1;
        while(b){
            if(b & 1) ret = ret * a;
            if(ret >= mod){
                ret = ret % mod + mod;
            }
            a = a * a;
            if(a >= mod){
                a = a % mod + mod;
            }
            b >>= 1;
        }
        return ret;
    }
    

    代码:

    #include<map>
    #include<set>
    #include<queue>
    #include<cmath>
    #include<stack>
    #include<ctime>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<sstream>
    #include<iostream>
    #include<algorithm>
    typedef long long ll;
    typedef unsigned long long ull;
    using namespace std;
    const int maxn = 1e5 + 5;
    const int MAXM = 3e6;
    const ll MOD = 998244353;
    const ull seed = 131;
    const int INF = 0x3f3f3f3f;
    
    ll euler(ll n){
        ll res = n, a = n;
        for(int i = 2; i * i <= a; i++){
            if(a % i == 0){
                res = res / i * (i - 1);
                while(a % i == 0) a/= i;
            }
        }
        if(a > 1) res = res / a * (a - 1);
        return res;
    }
    ll ksm(ll a, ll b, ll mod){
        ll ret = 1;
        while(b){
            if(b & 1) ret = ret * a;
            if(ret >= mod){
                ret = ret % mod + mod;
            }
            a = a * a;
            if(a >= mod){
                a = a % mod + mod;
            }
            b >>= 1;
        }
        return ret;
    }
    ll f(ll a, ll mod){
        if(a == 0) return 1 >= mod? 1 % mod + mod : 1;
        if(mod == 1) return a >= mod? a % mod + mod : a;    //剪枝
        ll phm = euler(mod);
        ll b = f(a / 10, phm);
        return ksm(a % 10, b, mod);
    }
    int main(){
        int T;
        scanf("%d", &T);
        while(T--){
            ll n, m;
            scanf("%lld%lld", &n, &m);
            printf("%lld
    ", f(n, m) % m);  //这里要取模
        }
        return 0;
    }
    
    
    
  • 相关阅读:
    论文摘要
    memset/memcpy/strcpy
    error C2259: 'CException' : cannot instantiate abstract class解决
    IplImage 结构
    图像的深度和通道概念
    Oracle11g安装教程
    LSTM理解
    卷积神经网络CNN
    常见激活函数的介绍和总结
    TFIDF算法介绍
  • 原文地址:https://www.cnblogs.com/KirinSB/p/11517956.html
Copyright © 2011-2022 走看看