[AHOI2002]黑白瓷砖

P2561 [AHOI2002]黑白瓷砖

题目大意:

一共 \(\frac{n(n+1)}{2}\) 个六边形,组成一个等边形,六边形只有黑白,问有多少种不能通过旋转使其方案相同的染色方案数。

解题思路:

一看到黑白染色和计数,就是置换问题。

明显的 \(burnside\) 定理,一共有 \(6\) 种置换:

  1. 不动
  2. 转120度
  3. 转240度
  4. 三种不同方向的翻折。

不动:循环长度为 \(1\)

旋转:循环长度为 \(3\) ,但是有可能中间多出 \(1\) 块瓷砖,那么这块瓷砖怎么转都不会变,所以它的循环长度为 \(1\)

翻折:除了位于正中间的点他们循环长度为 \(1\) ,其它点循环长度为 \(2\)

对于同一个循环内的瓷砖,他们的颜色都相同,要么黑要么白,一共两种情况。

再套一个高精度模板即可。

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,m;
struct GJD{
	int len,a[410];
	GJD():len(1){memset(a,0,sizeof(a));}
	void jinwei(){
		for(int i=1;i<=len;i++)
		if(a[i]>9)
		{
			a[i+1]+=a[i]/10;
			a[i]%=10;
			if(i==len)len++;
		}
	}
	void operator +=(const GJD b){
		if(b.len>len)len=b.len;
		for(int i=1;i<=len;i++)a[i]+=b.a[i];
		jinwei();
	}
	GJD operator *(const int b){
		GJD re;re.len=len;
		for(int i=1;i<=len;i++)re.a[i]=a[i]*b;
		re.jinwei();
		return re;
	}
	GJD operator *(const GJD b){
		GJD re;re.len=len+b.len-1;
		for(int i=1;i<=len;i++)
		for(int j=1;j<=b.len;j++)
		re.a[i+j-1]+=a[i]*b.a[j];
		re.jinwei();
		return re;
	}
}two[410],ans;

int main()
{
	scanf("%d",&n);m=n*(n+1)/2;
	two[0].a[1]=1;
	for(int i=1;i<=400;i++)two[i]=two[i-1]*2;
	ans+=two[m];
	ans+=(two[m/3]*2)*(m%3>0?2:1);
	ans+=(two[(m-(n+1)/2)/2]*two[(n+1)/2])*3;
	int last=0;
	for(int i=ans.len;i>=1;i--)
	ans.a[i]+=last*10,last=ans.a[i]%6,ans.a[i]/=6;
	while(!ans.a[ans.len])ans.len--;
	for(int i=ans.len;i>=1;i--)printf("%d",ans.a[i]);
    system("pause");
    return 0;
    
}

posted @ 2021-09-09 19:27  Evitagen  阅读(45)  评论(0编辑  收藏  举报