题意
题意:f(n) = (n%10)^f(n/10)计算f(n)%m
预备知识
指数循环节
其实就是用来压缩指数的。
求
a
b
m
o
d
c
a^b mod \space c
abmod c
当b很大,long long都存不下时,根据公式
a
b
m
o
d
c
≡
a
b
%
p
h
i
[
m
]
+
p
h
i
[
m
]
m
o
d
c
a^bmod\space c\equiv a^{b\%phi[m]+phi[m]}mod \space c
abmod c≡ab%phi[m]+phi[m]mod c
压缩指数(只有当b>phi[m]才能使用)
证明不存在的 。。ORZ
题解
当n=0 f(n)=1
当n<10 f(n)=n
当n>=10 则需要递归求解,例如求f(10)%m就需要先求出f(1)%phi[m]+phi[m]
这里我一开始不理解为什么在快速幂里%mod+mod,后来想想反正取模在加法和乘法下封闭,可以把这整个操作看作是一次运算。
代码
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<set>
#include<queue>
#include<stack>
#include<math.h>
#include<map>
using namespace std;
typedef long long int ll;
#define lson rt<<1
#define rson rt<<1|1
//const ll mod=100000000;
const ll maxn=100;
const int inf=0x7f7f7f;
ll phi(ll n)
{
ll rea=n;
for(ll i=2;i*i<=n;i++)
{
if(n%i==0)
{
rea=rea/i*(i-1);
while(n%i==0)
n/=i;
}
}
if(n>1)
rea=rea/n*(n-1);
return rea;
}
ll qmod(ll a,ll b,ll mod)
{
ll c=1;
if(a>mod)
a=a%mod+mod;
while(b)
{
if(b&1)
{
c=c*a;
if(c>mod)
c=c%mod+mod;
}
a=a*a;
if(a>mod)
a=a%mod+mod;
b>>=1;
}
return c;
}
ll f(ll n,ll m)
{
if(n==0)
return 1;
if(n<10)
return n;
ll p=phi(m);
ll x=f(n/10,p);
ll ans=qmod(n%10,x,m);
return ans;
}
int main(){
int t;
cin>>t;
while(t--)
{
ll n,m;
cin>>n>>m;
printf("%lld\n",f(n,m)%m);
}
}