poj 1286 &HDU 1817 Necklace of Beads

这是一个比较赤裸的群论题目,只是对他进行分步计算就可以了:

首先是旋转计算;在进行对称计算,这时候我们要对它进行奇偶讨论,当为奇数是我们就以每个顶点与它的对边中点连线为对称轴,那么循环节为(n+1)/2;

当为偶数时:有两个种对称轴,一是以顶点连线,二是以边的中点连线,前者循环节为n/2,后者为n/2+1;

View Code
#include<iostream>
 #include<cstdio>
 #include<cstdlib>
 #include<algorithm>
 #include<cmath>
 #include<queue>
 #include<set>
 #include<map>
 #include<cstring>
 #include<vector>
 #include<string>
 #define LL long long
 using namespace std;
 int Gcd( int a , int b )
 {
    return b ==0 ? a : Gcd( b , a % b );    
 }
 LL Pow( LL a , int n )
 {
    LL sum = 1;
    while( n )
    {
       if( n&1 ) sum *= a;
       n >>= 1;
       a *= a;
    }
    return sum;    
 }
 LL polya( int n )
 {
    if( n == 0 ) return 0;
    LL sum = 0;
    for( int i = 1 ; i <= n ; i ++ )
    {
         sum += Pow( 3LL , Gcd( i , n ) );        
    }
    if( n & 1 )
    {
        sum += Pow( 3LL , (n+1)/2 )*n;        
    }    
    else 
    {
       sum += Pow( 3LL , n/2 )*n/2;
       sum += Pow( 3LL ,n/2 + 1 )*n/2;    
    }
    return sum/(n*2);
 }
 int main(  )
 {
     int n;
     while( scanf( "%d",&n ),n != -1 )
     {
          printf( "%I64d\n",polya( n ) );    
     }
     //system( "pause" );
     return 0;
 }
 
posted @ 2012-09-10 20:22  wutaoKeen  阅读(210)  评论(0)    收藏  举报