码迷,mamicode.com
首页 > 其他好文 > 详细

UVA 10294 等价类计数

时间:2015-08-09 13:51:04      阅读:116      评论:0      收藏:0      [点我收藏+]

标签:

 题目大意:

项链和手镯都是若干珠子穿成的环形首饰,手镯可以旋转和翻转,但项链只能旋转,给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\n" , a/n , (a+b)/2/n);
30     }
31 }

 

UVA 10294 等价类计数

标签:

原文地址:http://www.cnblogs.com/CSU3901130321/p/4714935.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!