hdu3547(单纯polya定理)

题目大意:给你一个正方形,每个顶点可以从n种颜色里选择一种染上,问本质不同的有多少种,答案大于15位则只保留后面15位。

分析:

因为视角的原因,我们会把本质相同的正方形当作好几种。。

比如a正方形能经过旋转操作得到b正方形,那么a,b算是一种,也就是说a与b是等价的。

我们在群里就学过等价类的概念,而burnside引理就是用来统计等价类的个数。

polya定理则是对burnside引理的一个优化。

这个题主要则是研究置换:

1,不动,1个置换,8个循环节。

2,绕对立面的中心旋转,可以选择转90、180、270度,分别为2、4、2个循环节,又有3个对立面,共9个置换。

3,绕正方体体内的对角线旋转,可以选择转120、240度,都为4个循环节,又有4个对角线,共8个置换。

4,将正方体的正面摆成菱形那样子,可以选择转180度,有4个循环节,又有6个面,共6个置换。

所以,一共24个置换,整理可得到公式 (n^8+17n^4+6n^2)/24,避免超longlong,用java大数做就行了。

需要注意的是:不能对置换重复计数,如果在置换中,两两交换的对象都是一样的,那么便是一样的置换;

       当然,也不能漏掉一些置换,比如本题需要考虑3种对称轴,每种对称轴旋转的度数不一样也产生了不一样的置换。

 1 package test;
 2 import java.math.BigInteger;
 3 import java.util.Scanner;
 4 
 5 public class Main
 6 {
 7  
 8        public static void main(String[] args) 
 9        {
10                Scanner cin=new Scanner(System.in);
11               int t=cin.nextInt();
12               int d=1;
13               while(t>0)
14               {
15                   t--;
16                   
17                   BigInteger n=cin.nextBigInteger();
18                   System.out.print("Case "+d+": ");
19                   d++;
20                   BigInteger sum1=n.pow(8);
21                   BigInteger sum2=n.pow(4).multiply(BigInteger.valueOf(17));
22                   BigInteger sum3=n.pow(2).multiply(BigInteger.valueOf(6));
23                   String res=sum1.add(sum2).add(sum3).divide(BigInteger.valueOf(24)).toString();
24                   if(res.length()<=15) System.out.println(res);
25                   else System.out.println(res.substring(res.length()-15, res.length()));
26                   
27               }
28               cin.close();
29       }
30 }

 

 

 

posted @ 2018-10-11 14:22  hzhuan  阅读(309)  评论(0编辑  收藏  举报