poj1286

旋转:
–n个点顺时针旋转i个位置的置换,循环数为gcd(n,i),方案数为3gcd(n,i)
翻转:
–n为偶数时,对称轴不过顶点的循环数为n/2,方案数为3n/2对称轴过顶点的循环数为n/2+1,方案数为3n/2+1
–n为奇数时,循环数为(n+1)/2,方案数为3(n+1)/2

 

 

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
using namespace std;
__int64 gcd(__int64 a,__int64 b)
{
    if (!b)
        return a;
    return gcd(b, a % b);
}
__int64 Pow(__int64 a,__int64 b)
{
    __int64 i;
    __int64 res=1;
    for(i=0;i<b;i++)
    {
        res*=a;
    }
    return res;
}
int main()
{
    __int64 n;
    while(scanf("%I64d",&n),n+1)
    {
        if(n==0)
        {
            printf("0\n");
            continue;
        }
        __int64 counter=0;
        __int64 i;
        __int64 counter2=0;//置换数
        for(i=1;i<=n;i++)
        {
            counter+=Pow(3,gcd(i,n));
            counter2++;
        }
        if(n&1)
        {
            counter+=Pow(3,(n+1)/2)*n;
            counter2+=n;
            printf("%I64d\n",counter/counter2);
        }
        else
        {
            counter+=Pow(3,n/2)*(n/2);
            counter2+=(n/2);
            counter+=Pow(3,(n/2)+1)*(n/2);;
            counter2+=(n/2);
            printf("%I64d\n",counter/counter2);
        }
    }
    return 0;
}


posted @ 2012-07-22 21:09  willzhang  阅读(228)  评论(0编辑  收藏  举报