HDU 2837 Calculation

 题目大意,已知f(0) = 1 且 f(n) = (n%10)^f(n/10)  ,

输入n,m, 输出 f(n)%m   ----   (2 ≤ n , m ≤ 10^9)

要应用到一道公式

其中phi()为欧拉函数,当条件成立时,可以利用该公式进行加速幂

AC大神的blog有对于此公式的详细证明:    http://hi.baidu.com/aekdycoin/blog/item/b6f1762565bb403fc8955908.html 

然后注意公式使用的条件,注意一下0^0=1, 处理好细节就能过了

 

当然我没试过单纯快速幂能不能过,应该是没什么问题的,感觉这题数据强度不是太大

不过对于HDU 3609 和 09上海区预赛B题,(hdu 3221), 就必须用到了

 

#include<iostream>
using namespace std;
char n[10];
int m[10];
__int64 eular(__int64 num)
{
    __int64 ret=1;
    for(int i=2;i*i<=num;i++)
    {
        if(num%i==0)
        {
            num/=i;ret*=i-1;
            while(num%i==0) {num/=i;ret*=i;}
        }
    }
    return num>1? ret*(num-1):ret;
}
__int64 power(__int64 num,__int64 k,__int64 mod)
{
    if(num==0)
    {
        if(k!=0) return 0;
        else return 1;
    }
    __int64 res=1;
    while(k)
    {
        if(k&1)
        {
            res=res*num%mod;
            if(res==0) res=mod;
        }
        num= (num%mod) * (num%mod) % mod;
        k>>=1;
    }
    return res;
}
void init(int mm,int l)
{
    m[1]=mm;
    for(int i=2;i<=l+1;i++)
        m[i]=eular(m[i-1]);
}
int main()
{
    int tt,mo;
    scanf("%d",&tt);
    while(tt--)
    {
        scanf("%s%d",&n,&mo);
        int l=strlen(n);
        init(mo,l);
        __int64 ans=1;
        for(int i=0;i<l;i++)
        {
            if(ans!=0)
            {
                ans%=m[l-i];
                if(ans==0) ans=m[l-i];
            }
            ans=power(n[i]-'0',ans,m[l-i]);
        }
        printf("%I64d\n",ans);
        memset(n,0,sizeof(0));
    }
    return 0;
}


 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值