zoj 2674 Strange Limit——欧拉函数

watashi大神推荐的题目就是给里呀~~~

大意:求aa..a%m!的极限。

欧拉定理的内容是:如果a和n互质,那么aφ(n)=1(mod n);对于任意a, n和较大的b,有ab=aφ(n)+b mod φ(n)(mod n)

我们设aa..a=A

则有A=aφ(n)+A mod φ(n)(mod n)

这样就可以递归求解。因为φ(n)<n,所以这样递归一定有边界。

接下来就是上欧拉函数模版,素数筛模版了。。

另:要用longlong,不然会悲剧。。

PS:还跟watashi大神学习了每组数据之间分空行,最后一组数据后面没有空行怎么打的问题~~

2011-08-31 21:58:22 Accepted 2674 C++ 0 232 LadyTutu
#include<cstdio>
#include
<cstdlib>
#include
<cstring>
#include
<cmath>
#include
<algorithm>
#define PRIME 3000
#define MAXN 30000

long long prime[PRIME+10];
bool isprime[MAXN+10];
long long top;

void init(void)
{
long long i,j;
for(i=2;i<=MAXN;i++)
{
if(!isprime[i]) prime[top++]=i;
for(j=0;j<top&&i*prime[j]<=MAXN;j++)
{
isprime[i
*prime[j]]=true;
if(i%prime[j]==0) break;
}
}
top
--;
isprime[
1]=true;
}

long long euler(long long n)
{
long long i;
long long _n=n;
long long total=n;
for(i=0;i<=top&&prime[i]*prime[i]<=n;i++)
{
if(n%prime[i]==0)
{
total
=total/prime[i]*(prime[i]-1);
while(_n%prime[i]==0)
{
_n
/=prime[i];
}
}
}
if(_n!=1)
{
total
=total/_n*(_n-1);
}
return total;
}

long long quickmod(long long a,long long n,long long p)
{
if(n==0)
return 1%p;
if(n==1)
return a%p;
a
%=p;
long long ans=quickmod(a,n/2,p)%p;
ans
=ans*ans%p;
if(n&1)
ans
=ans*a%p;
return ans%p;
}

long long fac(long long m)
{
if(m==1)
return 1;
else return m*fac(m-1);
}

long long calc(long long a,long long m)
{
if(m==1)
return 0;
else
{
long long temp=euler(m);
return quickmod(a,temp,m)*quickmod(a,calc(a,temp),m);
}
}

int main(void)
{
long long a,m;
init();
bool blank=false;
while(scanf("%lld %lld",&a,&m)==2)
{
if(blank)
{
puts(
"");
}
else blank=true;
m
=fac(m);
printf(
"%lld\n",calc(a,m)%m);
}
return 0;
}

  

posted @ 2011-08-31 22:07  ω 提拉米兔 ℃  阅读(579)  评论(0编辑  收藏  举报