公式:
n^x mod m=n ^(φ(m)+x%φ(m))
当且仅当x>φ(m)时成立。
更具体
有关题目
hdu2837
模板题:
#include <cstdio>//欧拉降幂
#include <cstring>
using namespace std;
typedef long long ll;
ll euler(ll x)
{
ll res=x;
for(ll i=2;i*i<=x;i++)
{
if(x%i==0)
{
res-=(res/i);
while(x%i==0)
x/=i;
}
}
if(x>1)
res-=(res/x);
return res;
}
ll f_pow(ll a,ll b,ll mod)
{
ll res=1;
while(b)
{
if(b&1)
{
res=res*a;
if(res>=mod)//!
res=res%mod+mod;
}
a=a*a;
if(a>=mod)//!
a=a%mod+mod;
b>>=1;
}
return res;
}
ll dfs(ll a,ll b)
{
if(a==0)
return 1;
ll tmp=euler(b);
return f_pow(a%10,dfs(a/10,tmp),b);
}
int main()
{
int t;
ll n,m;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld",&n,&m);
printf("%lld\n",dfs(n,m)%m);
}
return 0;
}
fzu 1759
模板
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int N=1e6+5;
ll a,c;
char mi[N];
ll euler(ll x)
{
ll res=x;
for(ll i=2;i*i<=x;i++)
{
if(x%i==0)
{
res-=(res/i);//res写成了x,wa了好几次
while(x%i==0)
x/=i;
}
}
if(x>1)
res-=(res/x);
return res;
}
ll e_pow(ll x,ll y)
{
ll res=1;
while(y)
{
if(y&1)
res=res*x%c;
x=x*x%c;
y>>=1;
}
return res%c;
}
int main()
{
while(scanf("%I64d",&a)!=EOF)
{
memset(mi,'\0',sizeof(mi));
scanf("%s",mi);//printf("b=%s\n",mi);
scanf("%I64d",&c);
ll ec=euler(c);//printf("ec=%I64d\n",ec);
int len=strlen(mi);
ll tmp=0,tt=0;
int f=0;
for(int i=0;i<len;i++)
{
tt=tt*10+(mi[i]-'0');
if(tt>=ec)
{
f=1;
break;
}
}
if(f)
{
for(int i=0;i<len;i++)
{
tmp=tmp*10+(mi[i]-'0');
tmp%=ec;
}
tmp+=ec;
}
else
tmp=tt;
printf("%I64d\n",e_pow(a,tmp));
}
return 0;
}
hdu3221
主要是能够发现规律,根据题目可知次数有递推式f(n)=f(n-1)*f(n-2)。(一开始没发现),然后列举几项,就会发现对于每一个n,其答案里面的a,b的指数是按斐波那契数列的规则增长,因此可以用矩阵来计算,然后利用欧拉降幂。就能解决。
又一次因为矩阵相乘的地方超出int错了。
代码写的不太好。
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
ll n,p,a,b;
int ep,f;
struct matrix
{
ll mat[3][3];
void clc()
{
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
this->mat[i][j]=0;
}
matrix operator *(const matrix &b)const
{
matrix res;
res.clc();
for(int i=1;i<=2;i++)
{
for(int k=1;k<=2;k++)
{
if(this->mat[i][k])
{
for(int j=1;j<=2;j++)
{
if(f)
res.mat[i][j]=(res.mat[i][j]+(this->mat[i][k]*b.mat[k][j])%ep)%ep;
else
res.mat[i][j]=(res.mat[i][j]+this->mat[i][k]*b.mat[k][j]);
}
}
if((this->mat[1][1])>=ep)
f=1;
}
}
return res;
}
};
ll euler(ll x)
{
ll res=x;
for(ll i=2;i*i<=x;i++)
{
if(x%i==0)
{
res-=(res/i);
while(x%i==0)
x/=i;
}
}
if(x>1)
res-=(res/x);
return res;
}
matrix m_pow(matrix x,ll y)
{
matrix res;
res.clc();
for(int i=1;i<=2;i++)
res.mat[i][i]=1;
while(y)
{
if(y&1)
res=res*x;
x=x*x;
y>>=1;
}
return res;
}
ll f_pow(ll x,ll y)
{
ll res=1;
while(y)
{
if(y&1)
res=res*x%p;
x=x*x%p;
y>>=1;
}
return res%p;
}
void solve()
{
matrix A;
A.clc();
A.mat[1][1]=1;
A.mat[1][2]=1;
A.mat[2][1]=1;
ll ans=1,u;
matrix tmp;
f=0;
if(n>=2)
{
tmp=m_pow(A,n-2);
u=tmp.mat[1][1];//printf("b:u=%lld\n",u);
if(f)
u=u%ep+ep;
}
else
u=0;
ans=f_pow(b,u);
f=0;
if(n>=3)
{
tmp=m_pow(A,n-3);
u=tmp.mat[1][1];
if(f)
u=u%ep+ep;
}
else
{
if(n==1)
u=1;
if(n==2)
u=0;
}//printf("a:u=%lld\n",u);
ans=(ans*f_pow(a,u))%p;
printf("%lld\n",ans);
}
int main()
{
int t,cas=0;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld%lld%lld",&a,&b,&p,&n);
ep=euler(p);
printf("Case #%d: ",++cas);
solve();
}
return 0;
}