f[0]=1; f[n]=f[n%10]^f[n/10]; ^这里表示次方
给定n,m,求f[n]%m;
n,m<=10^9,那么求f[n]最多只需递归log次,问题关键是处理取余。
欧拉降幂:
注意指数是否需要加PHI(C).
题目地址:点击打开链接
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
bool use[32000];
int P_num,pri[32000];
void init()
{
memset(use,0,sizeof(use));
P_num=0;
for (int i=2;i<32000;i++)
{
if (!use[i]) pri[++P_num]=i;
for (int j=1;j<=P_num&&i*pri[j]<32000;j++)
use[i*pri[j]]=true;
}
}
int pow_M(int a,int b,int M)
{
int ans=1;
while (b)
{
if (b&1) ans=(ll)ans*a%M;
b>>=1;
a=(ll)a*a%M;
}
return ans;
}
int PHI(int x)
{
int ans=x;
for (int i=1;i<=P_num&&x>=pri[i];i++)
{
if (x%pri[i]==0)
{
ans=ans/pri[i]*(pri[i]-1);
while (x%pri[i]==0) x/=pri[i];
if (x==1) break;
}
}
if (x!=1)
ans=ans/x*(x-1);
return ans;
}
int cal(int n,int m)
{
if (n==0) return 1;
else if (n<10) return n;
else
{
int M=PHI(m);
int t=cal(n/10,M);
if (t>M){ t%=M; if (t==0&&n/10>0) t=M;}
int tmp=pow_M(n%10,t,m);
if (t>0&&tmp==0&&n%10>0) tmp=m;
return tmp;
}
}
int main()
{
init();
int T;
scanf("%d",&T);
while (T-->0)
{
int n,m;
scanf("%d%d",&n,&m);
printf("%d\n",cal(n,m)%m);
}
return 0;
}