zoukankan      html  css  js  c++  java
  • POJ-2409 Let it Bead 【置换群-Polya定理】

    题目链接:http://poj.org/problem?id=2409

    Time Limit: 1000MS   Memory Limit: 65536K

    Description

    "Let it Bead" company is located upstairs at 700 Cannery Row in Monterey, CA. As you can deduce from the company name, their business is beads. Their PR department found out that customers are interested in buying colored bracelets. However, over 90 percent of the target audience insists that the bracelets be unique. (Just imagine what happened if two women showed up at the same party wearing identical bracelets!) It's a good thing that bracelets can have different lengths and need not be made of beads of one color. Help the boss estimating maximum profit by calculating how many different bracelets can be produced. 

    A bracelet is a ring-like sequence of s beads each of which can have one of c distinct colors. The ring is closed, i.e. has no beginning or end, and has no direction. Assume an unlimited supply of beads of each color. For different values of s and c, calculate the number of different bracelets that can be made.

    Input

    Every line of the input file defines a test case and contains two integers: the number of available colors c followed by the length of the bracelets s. Input is terminated by c=s=0. Otherwise, both are positive, and, due to technical difficulties in the bracelet-fabrication-machine, cs<=32, i.e. their product does not exceed 32.

    Output

    For each test case output on a single line the number of unique bracelets. The figure below shows the 8 different bracelets that can be made with 2 colors and 5 beads.

    Sample Input

    1 1
    2 1
    2 2
    5 1
    2 5
    2 6
    6 2
    0 0
    

    Sample Output

    1
    2
    3
    5
    8
    13
    21



    题目大意:给你c中颜色,s长度的项链,问有多少种本质不同的染色方案(可通过旋转,翻转得到的为同一种)。
    很显然这题要用到置换群的相关知识,而很显然这题如果一个一个找不动点的话很麻烦,我们直接找循环节数就好了,然后用Polya定理一波带走。。

    首先对于旋转,很明显其置换群的元素|G|=n(有n种置换)分别为步长为1到n的置换,举个例子,对于项链长度为4的时候:
    1 2
    3 4
    旋转步长为1,那么循环节数为1:(1,2,4,3)
    步长为2,循环节数为2:(1,4)(2,3)
    步长为3,循环节数为1:(1,3,4,2)
    步长为4,循环节数为4:(1)(2)(3)(4)

    我们可以知道步长为i时循环节长度为LCM(n,i)/i,那么其循环节节数为n/(LCM(n,i)/i),即gcd(n,i)
    那么对于步长为i的一种置换,其方案数为c^gcd(n,i)

    接下来就是翻转了,翻转分奇数偶数:
    当n为奇数的时候:

    选择1个顶点,划开两边,则有n个顶点,即n种置换,每种置换有n/2+1个循环节,如上图:设1为顶点,即循环节为:(1)(2,3)

    当n为偶数的时候,又分为2种情况:

    对于第一种情况没有不动点,那么循环节数为n/2,有n/2种翻转(即沿(1,2)翻转,沿(1,3)翻转...)
    对于第二种情况又两个不动点,那么循环节数为(n-2)/2+2=(n+2)/2,也有n/2种翻转。

    那么根据Polya定理就可以愉快地得出答案了。
    以下是AC代码:
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    int qick(int a,int b)
    {
        int ans=1;
        while (b){
            if (b&1) ans=ans*a;
            a*=a;
            b>>=1;
        }
        return ans;
    }
    
    int gcd(int a,int b)
    {
        return b==0?a:gcd(b,a%b);
    }
    
    int main()
    {
        int c,n;
        while (scanf ("%d%d",&c,&n)){
            if (c==0 && n==0) break;
            int ans=0;
            for (int i=1; i<=n; i++){
                ans+=qick(c,gcd(n,i));
            }
            if (n&1) ans+=qick(c,(n+1)/2)*n;
            else ans+=qick(c,n/2)*n/2+qick(c,(n+2)/2)*n/2;
            printf ("%d
    ",ans/(n*2));
        }
        return 0;
    }


    路漫漫兮
  • 相关阅读:
    Javascript网页摇一摇
    移动端Web开发注意点
    Clappr——开源的Web视频播放器
    光看这图片就知道是大片--今天是五一劳动节尽管还是敲着代码(日常就是这样)然后想不出写什么了,也找不到好的素材,最后开心一下吧
    大放异彩的伪元素——可以做什么?(转)别人分享的文章,发现很不错,果断收藏了
    全屏滚动效果H5FullscreenPage.js
    今天我已无力吐槽了!写个没有营养的吐槽文。只是个人日记
    css的一些小技巧!页面视觉差!
    CSS3 transforms 3D翻开
    Javascript非构造函数的继承
  • 原文地址:https://www.cnblogs.com/lonely-wind-/p/12186739.html
Copyright © 2011-2022 走看看