• UVa10294


    10294 Arif in Dhaka (First Love Part 2)
    Our hero Arif is now in Dhaka (Look at problem 10244 – First Love if you want to know more about
    Arif, but that information is not necessary for this problem. In short, Arif is a brilliant programmer
    working at IBM) and he is looking for his first love. Days pass by but his destiny theory is not working
    anymore, which means that he is yet to meet his first love. He then decides to roam around Dhaka on
    a rickshaw (A slow vehicle pulled by human power), running DFS (by physical movement) and BFS
    (with his eyes) on every corner of the street and market places to increase his probability of reaching
    his goal. While roaming around Dhaka he discovers an interesting necklace shop. There he finds some
    interesting necklace/bracelet construction sets. He decides to buy some of them, but his programmer
    mind starts looking for other problems. He wants to find out how many different necklace/bracelet can
    be made with a certain construction set. You are requested to help him again. The following things
    are true for a necklace/bracelet construction set.
    a) All necklace/bracelet construction sets has a frame, which has N slots to place N beads.
    b) All the slots must be filled to make a necklace/bracelet.
    c) There are t types of beads in a set. N beads of each type are there in the box. So the total
    number of beads is t  N (t multiplied by N), of which exactly N can be used at a time.
    Fig. 1: Different types of necklace for t = 2 and different value of N
    The figure above shows necklaces for some different values of N (Here, t is always 2). Now let’s
    turn out attentions to bracelets. A bracelet is a necklace that can be turned over (A junior programmer
    in Bangladesh says that wrist watch is a necklace (Boys!!! Don’t mind :-))). So for a bracelet the
    following two arrangements are equivalent. Similarly, all other opposite orientation or mirror images
    are equivalent.
    Universidad de Valladolid OJ: 10294 – Arif in Dhaka (First Love Part 2) 2/2
    So, given the description of a necklace/bracelet construction set you will have to determine how
    many different necklace and bracelet can be formed with made with that set
    Input
    The input file contains several lines of input. Each line contains two positive integers N (0 < N < 51)
    and t (0 < t < 11) as described in the problem statement. Also note that within this input range inputs
    will be such that no final result will exceed 11 digits. Input is terminated by end of file.
    Output
    For each line of input produce one line of output which contains two round numbers NN and NB
    separated by a single space, where NN is the number of total possible necklaces and NB is the number
    of total possible bracelets for the corresponding input set.
    Sample Input
    5 2
    5 3
    5 4
    5 5
    Sample Output
    8 8
    51 39
    208 136
    629 377

    题意:

           项链和手镯都是由若干珠子穿成的环形首饰,区别在于手镯可以翻转但项链不能翻转。输入整数n和t,分别输出用t种颜色的n颗珠子(每种颜色的珠子颗数不加以限制)能制作的项链个数和手镯的个数。

    分析:

           等价类计数问题。一共有两种置换,选择以及翻转。项链只有第一种置换,手镯则有两种置换。设所有珠子按逆时针编号0~n-1。

           旋转置换:如果逆时针旋转i颗珠子的间距,则珠子0、i、2i、…构成一个循环。这个循环有n/gcd(i,n)个元素。根据对称性,所有循环的长度相同,因此一共有n/(n/gcd(i,n)) = gcd(i,n)个循环。该置换的不动点数为t^(gcd(i,n))。所有置换的不动点总数为a = sum{t^gcd(i,n) | i = 0,1,…,n - 1}。

           翻转置换:分情况讨论。当n是奇数时,对称轴有n条,每条对称轴形成(n-1)/2个长为2的循环以及1个长为1的循环,即(n+1)/2个循环。这些置换的不动点总数是b=nt^((n+1)/2)。

    当n是偶数时,有两种对称轴。穿过珠子的对称轴有n/2条,各形成n/2-1个长为2的循环,还形成两个长为1的循环;不穿过珠子的对称轴有n/2条,各形成n/2个长为2的循环。这些置换的不动点总数是b = n / 2 * (t ^ (n / 2 + 1) + t ^ (n / 2))。

           根据Polya定理,项链总数为a/n,手镯总数是(a + b) / (2n)。

     1 #include <cstdio>
     2 #include <cmath>
     3 #define LL long long
     4 const int maxn = 50;
     5 int gcd(int x,int y){return y == 0 ? x : gcd(y,x % y);}
     6 int main(){
     7     int n,t;
     8     while(scanf("%d%d",&n,&t) == 2 && n){
     9         LL pow[maxn + 1];
    10         pow[0] = 1;
    11         for(int i = 1 ; i <= n ; i++) pow[i] = pow[i - 1] * t;
    12         LL a = 0;
    13         for(int i = 0 ; i < n ; i++) a += pow[gcd(i,n)];
    14         LL b = 0;
    15         if(n & 1) b = n * pow[(n + 1) / 2];
    16         else b = n / 2 * (pow[n / 2 + 1] + pow[n / 2]);
    17         printf("%lld %lld
    ",a / n,(a + b) / 2 / n);
    18     }
    19     return 0;
    20 }
    View Code
  • 相关阅读:
    [转]Docker学习笔记之一,搭建一个JAVA Tomcat运行环境
    ubuntu wifi连接出现Network service discovery disabled的解决办法
    使用java实现对称加密解密(AES),非对称加密解密(RSA)
    [转] mysql分区性能初探
    CyclicBarrier和CountDownLatch的使用
    oom 和 jvm crash的问题
    使用单元素枚举实现单例
    【转】mysql 计划事件
    用Linkedhashmap的LRU特性及SoftReference软引用构建二级缓存
    动态生成正则表达式
  • 原文地址:https://www.cnblogs.com/cyb123456/p/5818295.html
Copyright © 2020-2023  润新知