hdu -2837-Calculation

Assume that f(0) = 1 and 0^0=1. f(n) = (n%10)^f(n/10) for all n bigger than zero. Please calculate f(n)%m. (2 ≤ n , m ≤ 10^9, x^y means the y th power of x).
Input
The first line contains a single positive integer T. which is the number of test cases. T lines follows.Each case consists of one line containing two positive integers n and m.
Output
One integer indicating the value of f(n)%m.
Sample Input
2
24 20
25 20
Sample Output
16
5

题意:该题就是让我们求f(n)%m,并且 f(0) = 1 and 0^0=1. f(n) = (n%10)^f(n/10)
欧拉函数:
分析:很明显我们可以用递归进行操作,由于数是很大的,简单递归会爆掉,所以我们可以用欧拉公式进行求解。
欧拉公式:A^x % mo =A^ (x%phi[m]+phi[m]) %mo (满足公式的条件x>=phi[m])
phi[m]表示1到m之内,与m互质的对数(即欧拉函数的数值),我们可以套用模板也可以调用函数来求

int Euler(int n)
{
    int ret=n;
    for(int i=2;i<=sqrt(n);i++)
         if(n%i==0)
          {
                ret=ret/i*(i-1);//先进行除法防止溢出(ret=ret*(1-1/p(i)))
                while(n%i==0)
                          n/=i;
         }
        if(n>1)
              ret=ret/n*(n-1);
        return ret;
}
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;

ll get_ph(ll x)
{
    ll ans=x;
    for(ll i=2;i*i<=x;i++)
    {
        if(x%i==0)
        {
            ans=ans/i*(i-1);
            while(x%i==0) x=x/i;
        }
    }
    if(x>1) ans=ans/x*(x-1);//判断一下是否有一个比sqrtx)大的质因子
    return ans;
}
ll ksm(ll a,ll b,ll mod)
{
    ll ans=1;
    if(a==0) return b==0;
    while(b)
    {
        if(b&1) 
        {
            ans=(ans*a)%mod;
        }
        b>>=1;
        a=(a*a)%mod;
    }
    if(ans==0) ans=mod;//这里要注意的是这个题比较特殊,我们在取膜的时候可能会变成0,那么就会对递归回去的结果又影响,所以我们在ans=0的时候令ans=mod。
    return ans;
}
ll f(ll x,ll mod)
{
    if(x<10) return x;
    ll tmp=get_ph(mod);
    ll t=f(x/10,tmp);
    x=x%10;
    ll ans=ksm(x,t,mod);
    return ans;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        ll n,m;
        scanf("%lld%lld",&n,&m);
        printf("%lld\n",f(n,m)%m);  
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/mmk27_word/article/details/81227845
hdu