hdu 2837 Calculation【欧拉函数,快速幂求指数循环节】


欢迎关注__Xiong的博客: http://blog.csdn.net/acmore_xiong?viewmode=list

Calculation

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 1912    Accepted Submission(s): 413

链接:click me

Problem Description

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(0) = 1,0^0 =1,【注意,0的其他任意次方为0,虽然题没有直接给出~】,还已知f(n) = (n%10)^f(n/10),让你求f(n)%m. (2 ≤ n , m ≤ 10^9)

分析:

求解一个递归式,f(n)递归下去是需要多次求幂的,这样,我们就可以用指数循环节来降幂处理,公式如下图,phi(i)表示的i的欧拉函数值,其实指数循环节就是欧拉函数+快速幂的一个结合而已,在这个题里面需要特别注意的就是对0的处理,求0的多次方需要进行判断一下。

还有一种降幂的方法在我另外一篇博客上有详细的讲解,请参考《2015 CSUST校赛 - 超级快速幂【费马小定理】+【快速幂取模】》,追根溯源,其实费小马定理就是欧拉定理的一个拓展~,更多数论知识,请参考《数论基础的补充讲解》~

实现代码:

#include <set>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define FIN             freopen("input.txt","r",stdin)
#define FOUT            freopen("output.txt","w",stdout)
#define CASE(T)         for(scanf("%d",&T);T--;)
typedef __int64 LL;
int T;
LL N, M, P;
LL phi(LL n)
{
    LL ans = n;
    for(LL i = 2; i * i <= n; i++)
    {
        if(n % i == 0)
        {
            ans -= ans / i ;
            while(n % i == 0) n /= i;
        }
    }
    if(n > 1) ans -= ans / n ;
    return ans;
}
//迭代形式
//LL pow_mod(LL a, LL p, LL mod)
//{
//    LL ans = 1;
//    if(a == 0)  return p == 0;
//    while(p)
//    {
//        if(p & 1)
//        {
//            ans = ans * a % mod;
//            if(ans == 0) ans = mod;
//        }
//        a = a * a % mod;
//        p >>= 1;
//    }
//    return ans;
//}
LL pow_mod(LL a, LL b, LL MOD)
{
    if(b == 0) return 1;
    if(a == 0) return 0;
    LL x, ans;
    x = pow_mod(a, b >> 1, MOD);
    ans = x * x % MOD;
    if(b & 1) ans = (a * ans) % MOD;
    if(ans == 0) ans = MOD;
    return ans;
}
LL f(int n,int m)
{
    if(n < 10) return n;
    int x = f(n / 10,phi(m)),ans;
    ans = pow_mod(n % 10,x,m);
    return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
    FIN;
#endif // ONLINE_JUDGE
    CASE(T)
    {
        scanf("%I64d %I64d", &N, &M);
        LL ans = f(N,M);
        printf("%I64d\n", ans % M);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-05 21:12:53

hdu 2837 Calculation【欧拉函数,快速幂求指数循环节】的相关文章

hdu 3307 Description has only two Sentences (欧拉函数+快速幂)

Description has only two SentencesTime Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 852 Accepted Submission(s): 259 Problem Descriptionan = X*an-1 + Y and Y mod (X-1) = 0.Your task is to calculate th

XMU 1615 刘备闯三国之三顾茅庐(三) 【欧拉函数+快速幂+欧拉定理】

1615: 刘备闯三国之三顾茅庐(三) Time Limit: 1000 MS  Memory Limit: 128 MBSubmit: 45  Solved: 8[Submit][Status][Web Board] Description 刘备(161年-223年6月10日),字玄德,东汉末年幽州涿郡涿县,西汉中山靖王刘胜的后代.刘备一生极具传奇色彩,早年颠沛流离.备尝艰辛最终却凭借自己的谋略终成一方霸主.那么在那个风云激荡的年代,刘备又是如何从一个卖草鞋的小人物一步一步成为蜀汉的开国皇帝呢

Exponial (欧拉定理+指数循环定理+欧拉函数+快速幂)

题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=2021 Description Everybody loves big numbers (if you do not, you might want to stop reading at this point). There are many ways of constructing really big numbers known to humankind, for instanc

HDU 1695 GCD 欧拉函数+容斥原理+质因数分解

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1695 题意:在[a,b]中的x,在[c,d]中的y,求x与y的最大公约数为k的组合有多少.(a=1, a <= b <= 100000, c=1, c <= d <= 100000, 0 <= k <= 100000) 思路:因为x与y的最大公约数为k,所以xx=x/k与yy=y/k一定互质.要从a/k和b/k之中选择互质的数,枚举1~b/k,当选择的yy小于等于a/k时,可以

欧拉函数&amp;&amp;快速乘方

1 //phi(a)=a*(a1-1)*(a2-1)*(a3-1)*...*(an-1)/(a1*a2*a3*...*an); 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 typedef __int64 LL; 8 LL phi(LL a){//phi 9 LL temp=a; 10 for(LL

HDU 2824 简单欧拉函数

1.HDU 2824   The Euler function 2.链接:http://acm.hdu.edu.cn/showproblem.php?pid=2824 3.总结:欧拉函数 题意:求(a,b)间的欧拉函数值的和. #include<iostream> #include<cstring> #include<cmath> #include<queue> #include<algorithm> #include<cstdio>

HDU 2588 GCD (欧拉函数)

GCD Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1013    Accepted Submission(s): 457 Problem Description The greatest common divisor GCD(a,b) of two positive integers a and b,sometimes writt

【BZOJ 1409】 Password 数论(扩展欧拉+矩阵快速幂+快速幂)

读了一下题就会很愉快的发现,这个数列是关于p的幂次的斐波那契数列,很愉快,然后就很愉快的发现可以矩阵快速幂一波,然后再一看数据范围就......然后由于上帝与集合对我的正确启示,我就发现这个东西可以用欧拉函数降一下幂,因为两个数一定互质因此不用再加一个phi(m),于是放心的乘吧宝贝!! #include <cstdlib> #include <cstring> #include <cstdio> #include <iostream> #include &

hdu 1695 GCD(欧拉函数+容斥原理)

http://acm.hdu.edu.cn/showproblem.php? pid=1695 非常经典的题.同一时候感觉也非常难. 在区间[a,b]和[c,d]内分别随意取出一个数x,y,使得gcd(x,y) = k.问这种(x,y)有多少对.能够觉得a,c均为1,并且gcd(5,7)与gcd(7,5)是同一种. 由于gcd(x,y) = k,那么gcd(x/k,y/k) = 1.也就是求区间[1,b/k]和[1,d/k]内这种(x,y)对使得gcd(x,y) = 1. 为了防止计数反复,首先