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;

 }

 

你可能感兴趣的:(poj)