zoukankan      html  css  js  c++  java
  • UVA 10294 等价类计数

     题目大意:

    项链和手镯都是若干珠子穿成的环形首饰,手镯可以旋转和翻转,但项链只能旋转,给n个珠子,t种颜色,求最后能形成的手镯,项链的数量

    这里根据等价类计数的polya定理求解

    对于一个置换f,若一种方案经过置换后不改变,那么不改变的点的个数记作C(f)

    统计所有的C(f) , 相加之后求和除以置换的种数即可

    那么这道题里面

    对于项链来说,旋转一个角度,也就是2*PI/n , 那么置换群可表示为

    1 2 3 4 .... n

    2 3 4 5 ... 1

    这里就存在一个循环节

    所以方案数为 t^1

    自己 写着会发现,循环节的个数就是旋转数和总数的gcd值

    那么不动点的个数就是 sigma(t^(gcd(i,n))

    对于手镯除了上述情况,还有翻转

    对于 n 为奇数,翻转对称轴有n条,这样置换形成的循环节有 (n+1)/2

    对于 n 为偶数,翻转对称轴有n条,n/2条是不经过点的,这样置换形成的循环节有 (n)/2

    n/2条经过两个点的,这样置换形成的循环节有 (n)/2+1

     1 #include <cstdio>
     2 #include <cstring>
     3 
     4 using namespace std;
     5 #define ll unsigned long long
     6 int n , t;
     7 ll pow[51];
     8 
     9 int gcd(int a , int b){return b==0?a:gcd(b , a%b);}
    10 
    11 void init()
    12 {
    13     pow[1] = t;
    14     for(int i=2 ; i<=n ; i++) pow[i] = pow[i-1]*t;
    15 }
    16 int main()
    17 {
    18   //  freopen("in.txt" , "r" , stdin);
    19     while(~scanf("%d%d" , &n , &t)){
    20         init();
    21         ll a=0 , b=0;
    22         for(int i=1 ; i<=n ; i++){
    23             a += pow[gcd(i , n)];
    24         }
    25         if(n&1) b+= pow[(n+1)/2]*n;
    26         else{
    27             b+=(n/2)*(pow[n/2]+pow[n/2+1]);
    28         }
    29         printf("%lld %lld
    " , a/n , (a+b)/2/n);
    30     }
    31 }
  • 相关阅读:
    她又在这个星期联系我了 20110422
    用心去做 20110307
    2011年随笔记
    让我有勇气坚持下去 20110427
    2011年随笔记 5月30号以后的日志薄
    因为迷失,所以 201103015
    迷失只是暂时 20110313
    我们做一对好哥们吧 20101228
    3.20号,她恢复了联系 20110320
    FW: Deploy reporting services web parts (RSWebParts) to SharePoint 2010
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4714935.html
Copyright © 2011-2022 走看看