POJ 2409 Let it Bead / 1286 Necklace of Beads Polya 计数

题意:用k种不同的颜色给长度为n的项链染色。

题解:

1.旋转置换:一个有n个旋转置换,依次为旋转0,1,2,```n-1。对每一个旋转置换,它循环分解之后得到的循环因子个数为gcd(n,i).

2.翻转置换:分奇偶讨论。

奇数的时候 翻转轴 = (顶点+对边终点的连线),一共有n个顶点,故有n个置换,且每个置换分解之后的因子个数为n/2+1;   

偶数的时候 翻转轴 = (顶点+顶点的连线),一共有n个顶点,故有n/2个置换,且每个置换分解之后的因子个数为n/2+1;  或者 翻转轴 = (边终点+边中点的连线),一共有n个顶点,故有n/2个置换,且每个置换分解之后的因子个数为n/2;      

#include<cmath>
#include<cstdio>
using namespace std;
#define lint __int64

int gcd ( int a, int b )
{
    return b ? gcd ( b, a % b ) : a;
}

lint exp ( lint a, int b )
{
    lint ret = 1;
    while ( b >= 1 )
    {
        if ( b & 1 ) ret *= a;
        a = a * a;
        b >>= 1;
    }
    return ret;
}

lint Polya ( int k, int n )
{
    lint ret = 0;
    for ( int i = 0; i < n; i++ )
        ret += exp (k, gcd (n,i));
    if ( n & 1 )
        ret += n * exp (k,n/2+1);
    else
        ret += n/2 * exp(k,n/2) + n/2 * exp(k,n/2+1);
    return ret / n / 2;
}

int main()
{
    int k, n;
    while ( scanf("%d%d",&k,&n) && (k||n) )
        printf("%I64d\n",Polya(k,n));
    return 0;
}

POJ 1286 Necklace of Beads

#include<cstdio>
#define lint __int64

lint power ( lint a, lint b )
{
    lint ret = 1;
    while ( b >= 1 )
    {
        if ( b & 1 ) ret *= a;
        a = a * a;
        b >>= 1;
    }
    return ret;
}

lint gcd ( lint a, lint b )
{
    return b ? gcd(b, a % b) : a;
}

lint polya ( lint n )
{
    lint ret = 0;
    for ( int i = 0; i < n; i++ )
        ret += power(3, gcd(i,n));
    if ( n & 1 )
        ret += n * power(3,n/2+1);
    else
        ret += n/2 * power(3,n/2) + n/2 * power(3,n/2+1);
    return ret / n / 2;
}

int main()
{

    lint n;
    while ( scanf("%I64d",&n) && n != -1 )
    {
        if ( n <= 0 ) printf("0\n");
        else printf("%I64d\n",polya(n));
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值