[AHOI2002]黑白瓷砖
P2561 [AHOI2002]黑白瓷砖
题目大意:
一共 \(\frac{n(n+1)}{2}\) 个六边形,组成一个等边形,六边形只有黑白,问有多少种不能通过旋转使其方案相同的染色方案数。
解题思路:
一看到黑白染色和计数,就是置换问题。
明显的 \(burnside\) 定理,一共有 \(6\) 种置换:
- 不动
- 转120度
- 转240度
- 三种不同方向的翻折。
不动:循环长度为 \(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;
}
不关注的有难了😠😠😠https://b23.tv/hoXKV9