• 【POJ】2409 Let it Bead


    题意:用k种颜色对n个珠子构成的环上色,旋转翻转后相同的只算一种,求不等价的着色方案数。

    Burnside定理的应用:

    当n为奇数时,有n种翻转,每种翻转都是以一个顶点和该顶点对边的中点对称。有k^(n/2+1)*n种。

    当n为偶数时,有n种翻转,其中一半是以两个对应顶点,另一半是以两条对边对称。有k^(n/2+1)*n/2+k^(n/2)*n/2种。

    考虑旋转:枚举旋转角度360/n*i,(0<i<=n),也就是一个置换。经过该置换,颜色仍保持不变的着色方案有k^GCD(n,i)种。

    一个长度为n的环,每i个上同一种颜色,可以上多少种颜色。

    假设起点在x,则x,x+i,x+2*i,……,x+k*i,……

    假设在第t次,第一次回到起点,则x=(x+t*i)%n => t*i%n=0 => t=LCM(i,n)/i=n*i/GCD(n,i)/i=n/GCD(n,i)。

    那么可以上n/t种颜色,即n/(n/GCD(n,i))种,所以旋转的着色方案有k^GCD(n,i)种。

     1 #include<cstdio>
     2 typedef long long LL;
     3 LL Pow(LL a, LL b) {
     4     LL ans;
     5     for (ans = 1; b; b >>= 1) {
     6         if (b & 1)
     7             ans *= a;
     8         a *= a;
     9     }
    10     return ans;
    11 }
    12 int GCD(int x, int y) {
    13     return y ? GCD(y, x % y) : x;
    14 }
    15 int main() {
    16     int n, k, i;
    17     LL ans;
    18     while (scanf("%d%d", &k, &n), n || k) {
    19         if (n & 1)
    20             ans = Pow(k, n / 2 + 1) * n;
    21         else
    22             ans = Pow(k, n / 2 + 1) * (n / 2)
    23                     + Pow(k, n / 2) * (n / 2);
    24         for (i = 1; i <= n; i++)
    25             ans += Pow(k, GCD(n, i));
    26         ans = printf("%lld\n", ans / (2 * n));
    27     }
    28     return 0;
    29 }
  • 相关阅读:
    点子
    点子
    ruby crawler Anemone
    创业站
    我友网 没前途
    创意
    电商站
    尿布
    创意
    青番茄好项目
  • 原文地址:https://www.cnblogs.com/DrunBee/p/2678378.html
Copyright © 2020-2023  润新知