链接:http://poj.org/problem?id=1286
http://poj.org/problem?id=2409
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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 }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <cstdio> 2 #include <iostream> 3 using namespace std; 4 int N, M; 5 typedef long long LL; 6 LL P_M(int a, int b ) 7 { 8 LL res=1,t=a; 9 while(b){ 10 if(b&1)res*=t; 11 t*=t; 12 b>>=1; 13 } 14 return res; 15 } 16 int gcd( int x, int y ) 17 { 18 return y==0?x:gcd( y, x%y ); 19 } 20 LL polya( int k, int m ) 21 { 22 LL ans=0; 23 for( int i=0; i<m; ++ i ){ 24 ans+=P_M(k, gcd( i, m )); 25 } 26 if( m&1 ){ 27 ans+=(LL)(m*P_M( k, m/2+1 ) ); 28 } 29 else { 30 ans+=(LL)m/2*P_M(k, m/2); 31 ans+=(LL)m/2*P_M(k, m/2+1); 32 } 33 if(m)ans/=2,ans/=m; 34 return ans; 35 } 36 int main( ) 37 { 38 while(scanf("%d%d", &N,&M)!=EOF, N+M ){ 39 printf("%lld\n", polya(N, M)); 40 } 41 return 0; 42 }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <cstdio> 2 #include <iostream> 3 using namespace std; 4 typedef long long LL; 5 const LL M=1e9+7; 6 LL P_M(int a, int b ) 7 { 8 LL res=1,t=a; 9 while(b){ 10 if(b&1)res*=t, res%=M; 11 t*=t, t%=M; 12 b>>=1; 13 } 14 return res; 15 } 16 int gcd( int x, int y ) 17 { 18 return y==0?x:gcd( y, x%y ); 19 } 20 LL polya( int k, int m ) 21 { 22 LL ans=0; 23 for( int i=0; i<m; ++ i ){ 24 ans+=P_M(k, gcd( i, m )); 25 ans%=M; 26 } 27 if( m&1 ){ 28 ans+=(LL)(m*P_M( k, m/2+1 ) ); 29 } 30 else { 31 ans+=(LL)m/2*P_M(k, m/2); 32 ans+=(LL)m/2*P_M(k, m/2+1); 33 } 34 ans%=M; 35 return (ans*P_M(2*m,M-2))%M;// 求逆元 36 } 37 int main( ) 38 { 39 int T, N, K, t=1; 40 scanf("%d", &T); 41 while(T--){ 42 scanf("%d%d", &N,&K); 43 printf("Case #%d: %I64d\n", t++, polya(N, K)); 44 } 45 return 0; 46 }