等价类计数问题,我们就先构造置换群
显然置换分为两种类型,旋转和翻折
先考虑旋转,每旋转i格子,这个置换的循环数为gcd(i,n); (1<=i<=n) 为什么是这个范围,下篇报告再说
翻转也是n种,显然要分奇偶讨论
奇数时,翻转只能从顶点,都是一个类型的,循环数位(n+1)/2
偶数时,翻转既能沿边折,循环数为n/2,又可以沿关于圆心的对称点连线折,循环数为(n-2)/2+2=(n+2)/2
然后直接套一下polya定理就可以了,还是比较简单容易分析出来的
1 var d:array[0..30] of int64; 2 i,n:longint; 3 ans:int64; 4 5 function gcd(a,b:longint):longint; 6 begin 7 if b=0 then exit(a) 8 else exit(gcd(b,a mod b)); 9 end; 10 11 begin 12 readln(n); 13 d[0]:=1; 14 for i:=1 to 24 do 15 d[i]:=d[i-1]*3; 16 17 while n<>-1 do 18 begin 19 if n=0 then writeln(0) 20 else begin 21 ans:=0; 22 for i:=1 to n do 23 ans:=ans+d[gcd(n,i)]; 24 if n mod 2=1 then ans:=ans+n*d[(n+1) div 2] 25 else ans:=ans+n div 2*d[n div 2]+n div 2*d[(n+2) div 2]; 26 writeln(ans div 2 div n); 27 end; 28 readln(n); 29 end; 30 end.