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 }