http://acm.hdu.edu.cn/showproblem.php?pid=3609
题意:
定义:a↑↑1 = a , a↑↑(k+1) = a (a↑↑k)
求 a↑↑k mod 100000000 .
思路:
A^x = A^( x % phi(C) + phi(C) ) ( mod C ) , x>= phi(C) ;
代码:
#include <stdio.h>
#include <string.h>
typedef __int64 LL ;
const LL Mod = 100000000 ;
const LL PP = 10002 ;
LL a, k ;
LL prime[1225] , cnt ;
bool is_p[PP] ;
LL phi[30] , pnum ;
LL get_phi(LL n){
LL res = n ;
for( int i=0;i<cnt && prime[i]*prime[i]<=n ; i++){
if( n % prime[i] == 0 ){
res = res / prime[i] * (prime[i] - 1) ;
while( n%prime[i] == 0) n /= prime[i] ;
}
}
if( n > 1 ) res = res / n * (n - 1) ;
return res ;
}
void calc(){
for(int i=1;i<PP;i++) is_p[i] = 1 ;
cnt = 0 ;
for(LL i=2;i<PP;i++){
if( is_p[i] ){
prime[ cnt++ ] = i ;
for( LL j=2;i*j<PP;j++)
is_p[i*j] = 0 ;
}
}
pnum = 0 ;
LL now = Mod , pre = Mod ;
phi[0] = now ; pnum ++ ;
while( true ){
phi[ pnum ] = get_phi( now ) ;
if( phi[pnum] == now ) break;
pre = now ;
now = phi[ pnum++ ] ;
}
}
LL pow( LL a, LL b , LL n){
LL res = 1 , add = a % n ;
while( b ){
if( b&1 ) res = res * add % n ;
add = add * add % n ;
b >>= 1;
}
return res ;
}
int large(LL a , LL b , LL p ){
LL res = a ;
for(int i=0;i<b && res<p ; i++ )
res = res * a ;
return res >= p ;
}
/*
make函数的作用是求 a↑↑k % p
如果 a↑↑k >= p ,返回 ( a↑↑k ) % p + p ;
如果 a↑↑k < p ,返回 ( a↑↑k ) % p ;
*/
LL make(LL a ,LL k ,LL num){ //a||k % p
if( num == pnum ) num -- ;
LL p = phi[num] ;
if( k==1 ){
if( a < p ) return a ;
else{
a %= p ; return a + p ;
}
}
LL bk = make( a , k-1 , num + 1 ) ;
LL ans = pow( a , bk , p ) ;
ans += large( a , bk , p )* p ;
return ans ;
}
int main(){
calc() ;
while( scanf("%I64d %I64d",&a,&k) == 2){
printf("%I64d\n", make(a, k ,0)%phi[0] ) ;
}
return 0 ;
}