链接:http://poj.org/problem?id=1286
http://poj.org/problem?id=2409
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 using namespace std; 7 typedef long long LL; 8 LL P_M( LL a, LL b ) 9 { 10 LL res=1, t=a; 11 while (b){ 12 if(b&1)res*=t; 13 t*=t; 14 b>>=1; 15 } 16 return res; 17 } 18 int a[30], vi[30]; 19 void dfs( int i ) 20 { 21 if( !vi[i] ){ 22 vi[i]=1; 23 dfs(a[i]); 24 } 25 } 26 27 int find(int t, int n ) // 求循环节 s == gcd( n, t ) ; 28 { 29 memset(vi, 0, sizeof vi); 30 memset(a, 0, sizeof a); 31 for( int i=1; i<=n; ++ i ){ 32 int e=(i+t-1)%n; 33 if( e==0 )e=n; 34 a[i]=e; 35 } 36 int s=0; 37 for( int i=1; i<=n; ++ i ){ 38 if(!vi[i]){ 39 dfs(i); 40 s++; 41 } 42 } 43 return s; 44 } 45 int gcd( int x, int y ) 46 { 47 return y==0?x:gcd( y, x%y ); 48 } 49 int main( ) 50 { 51 int N; 52 while( scanf("%d", &N)!= EOF){ 53 if( N==-1 )break; 54 if( N==0 ){puts("0"); continue;} 55 LL ans=0; 56 if( !(N&1) ){ 57 ans=P_M(3LL, N); 58 for( int i=2; i<=N; ++i ){ 59 int t=find(i, N); 60 ans+=P_M( 3LL,t ); 61 } 62 ans+=(LL)(N/2)*(P_M(3LL,(N+2)/2)); 63 ans+=(LL)(N/2)*P_M(3LL,N/2); 64 } 65 else{ 66 for( int i=0; i<N; ++i ){ 67 ans+=P_M(3LL, gcd(i, N)); 68 } 69 ans+=(LL)(N)*(P_M(3LL,N/2+1)); 70 71 } 72 printf( "%d\n", ans/(2*N) ); 73 } 74 return 0; 75 }