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

来源:互联网 发布:ubuntu 终端打不开 编辑:程序博客网 时间:2024/06/07 17:25

题意:用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 __int64int 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 __int64lint 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;}


原创粉丝点击