题目概述
一个N*N的棋盘,用C种颜色染色,其中将棋盘旋转后重合,沿中线对称,沿对角线对称的不重复计数,问一共多少种染色方案
时限
1000ms/3000ms
输入
每行两个整数N,C,输入到EOF为止
限制
1<=N,C<=30
输出
每行一个数,为所求染色方案数
样例输入
2 2
3 1
30 30
样例输出
6
1
320655918792067344519812003636174936042833134268573324773917290347588687195583228957681478991668111923702407658831752945563294531748541469620668824889067711874726866312058347438467661246388715694305613461331436880271971151648725980628811895543560805289647628359316951330416403383661240070590005929268290315984398017105289968558085794371861494786147758635495136464643814846486645602598173929069309466300544223502029291006048962250125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000181686832397051520946056308805604466407581978045474875359304082504155934507238826154311278029700058810684471274766758018118781558443619431822845272307989789502119217489434773675721830466291083197394510990672829006479672817871147951255843375000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000056262926820812101010816099729989223477132666830078100287001870103720151397131864096813133382596914690275360750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
讨论
数论,polya定理,如果不太清楚polya定理是什么,最好先去看一下蓝白书,好的,没走的应该都知道polya定理是什么了,按题目所言,置换有这样几种,没动,旋转90度,旋转180度,旋转270度,中线对称,对角线对称,没动的情况很明显,有多少格就有多少循环,这样是
N2
个循环,1种置换,旋转90度,只要知道三个旋转都是一个方向的就可以,每个格和其旋转90度后的格重合,这样每个循环节长度都是4,一共是
N22
,对吗?不对,N为奇数不对,因为中间的格自己算一个循环节,所以对奇数是
N2−14+1
,也就是
N2+34
,旋转270度时同理,这样共2种置换,旋转180度时循环节长度是2,偶数是
N22
,奇数是
N2−12+1
,即
N2+12
,1种置换,中线对称时,偶数直接就是
N22
,因为其循环节长度都是2,而奇数的中间部分循环节长度都只有1,这样是
N2−N2+N
,即
N2+N2
,这样的对称轴水平竖直各一根,这是2种置换,对角线时,奇偶都一样,因为对角线的格子循环节长度都是1,这样就都是
N2+N2
,同样对角线有2根,这是2种循环,最后,按polya定理乘方,加和,取平均,就是结果了
实现层面上,数据规模不大,乘方不用自己写了,但另一方面也不难发现最终结果是相当的大,用java大数解决可以方便一些,不会?那就用c++大数模版吧
题解状态
780MS,14216K,938 B,Java
题解代码
import java.io.*;
import java.math.*;
import java.util.*;
public class Main {
static int N;
static BigInteger C;
public static void main(String[] args) throws Exception {
//System.setOut(new PrintStream(new FileOutputStream("ij_cout.txt")));
System.setIn(new FileInputStream("ij_cin.txt"));
Scanner cin = new Scanner(new BufferedInputStream(System.in));
while (cin.hasNext()) {
N = cin.nextInt();
C = cin.nextBigInteger();
if (N % 2 == 1)
System.out.println(C.pow((N * N + 3) / 4).multiply(BigInteger.valueOf(2)).add(C.pow((N * N + 1) / 2)).add(C.pow(N * N)).add(C.pow((N * N + N) / 2).multiply(BigInteger.valueOf(4))).divide(BigInteger.valueOf(8)));
else
System.out.println(C.pow(N * N / 4).multiply(BigInteger.valueOf(2)).add(C.pow(N * N / 2).multiply(BigInteger.valueOf(3))).add(C.pow(N * N)).add(C.pow((N * N + N) / 2).multiply(BigInteger.valueOf(2))).divide(BigInteger.valueOf(8)));
}
}
}
EOF