G - Calculation【欧拉公式降幂】

Discription
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) = (n%10)^f(n/10)(其中x^y 表示x的y次方)
而且f(0) = 1 并且 0^0=1
输入两个数:n和m
求出f(n)%m的值。

思路
这道题是一个x的幂次的幂次的形式。
例如 f(23456)=6 ^5 ^4 ^3 ^2;
所以需要用到欧拉公式降幂
公式为:
在这里插入图片描述

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;

///直接求解一个数n的欧拉函数
LL euler(LL n)  //返回euler(n)
{
    LL res=n,a=n;
    for(LL 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 qmi(LL m, LL k, LL p)
{
    LL res = 1, t = m;
    while (k)
    {
        if (k&1)
        {
            res = res * t ;
            if(res>p)
                res=res%p+p;
        }
        t = t * t;
        if(t>p)
            t=t%p+p;
        k >>= 1;
    }
    return res;
}


LL F(LL n,LL m)
{
    if(n<10)
        return n;
    LL phi=euler(m);
    LL tt=F(n/10,phi);
    return qmi((n%10),tt,m);
}

LL n,m;
int t;

int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lld %lld",&n,&m);
        printf("%lld\n",F(n,m)%m);
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值