您的位置:首页 > 其它

UVA 11255 Necklace(Burnside引理)

2013-02-23 21:38 411 查看
题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2222

题意:有三种不同颜色的珠子,白(W颗),灰(G颗),黑(B颗), 其中3<=W+G+B<=40,问用这些珍珠可以串成多少种(W+G+B)长的不同的项链(项链可在平面内转动,也可翻转)。

思路:令n=W+G+B,(1)旋转:想想,对于每一种置换,我们要找出在这种置换下哪些排列在置换后还是这样。旋转有n种情况,分别是旋转0,1,2……,n-1个。比如,旋转2,设n=12,那么所有的分成2组,每组6个。这两组要保持一样,那么WGB在每组中的个数和排列方式是一样的,此时必须WGB都是偶数才行,进而问题转化成W/2,G/2,B/2个在一组中的排列的个数有多少种(另一组跟这组的排列一样无需再计算),这就是一个简单的组合计算。因此,枚举n的约数i,k=n/Gcd(n,i),WGB都是k的倍数才可以,然后就是W/k、G/k、B/k的排列;(2)翻转:WGB中有0个奇数,绕对边的轴转和绕相对的顶点的轴转;有1个奇数,绕一个顶点一条边中点的轴转;有2个奇数,设WG为奇数,绕两个相对顶点的轴转,两个顶点分别是WG。

void init()
{
int i,j;
C[0][0]=1;
FOR1(i,40)
{
C[i][0]=C[i][i]=1;
FOR1(j,i-1) C[i][j]=C[i-1][j]+C[i-1][j-1];
}
}

int Gcd(int x,int y)
{
return !y?x:Gcd(y,x%y);
}

int x,y,z,n,T;

int main()
{
init();
RD(T);
while(T--)
{
RD(x,y,z);
n=x+y+z;
int i,k;
u64 ans=0;
FOR1(i,n)
{
k=n/Gcd(n,i);
if(x%k==0&&y%k==0&&z%k==0)
{
ans+=C[n/k][x/k]*C[(y+z)/k][y/k];
}
}
int cnt=x%2+y%2+z%2;
if(cnt==1)
{
if(x&1) ans+=C[n/2][(x-1)/2]*C[(y+z)/2][y/2]*n;
else if(y&1) ans+=C[n/2][(y-1)/2]*C[(x+z)/2][x/2]*n;
else ans+=C[n/2][(z-1)/2]*C[(x+y)/2][x/2]*n;
}
else if(cnt==0)
{
ans+=n/2*C[n/2][x/2]*C[(y+z)/2][y/2];
if(x>=2) ans+=n/2*C[n/2-1][x/2-1]*C[(y+z)/2][y/2];
if(y>=2) ans+=n/2*C[n/2-1][y/2-1]*C[(x+z)/2][x/2];
if(z>=2) ans+=n/2*C[n/2-1][z/2-1]*C[(x+y)/2][x/2];
}
else if(cnt==2)
{
if(x%2==0) ans+=n*C[n/2-1][x/2]*C[(y+z-2)/2][(y-1)/2];
else if(y%2==0) ans+=n*C[n/2-1][y/2]*C[(x+z-2)/2][(x-1)/2];
else ans+=n*C[n/2-1][z/2]*C[(x+y-2)/2][(x-1)/2];
}
PR(ans/(2*n));
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: