Necklace UVA

来源:互联网 发布:淘宝男装店铺 编辑:程序博客网 时间:2024/05/17 23:48

题意:

给定特定个数的 黑色,灰色,白色珠子形成一个手串,手串可以翻转,旋转

思路:

利用burnside定理,计算各种置换群下的不动点个数

旋转:

gcd计算循环节个数,得倒每个的循环节长度,

反转:

分开奇偶,对称轴

#include<bits/stdc++.h>#define ll long longusing  namespace std;int a,b,c;ll C[45][45];void init(){    for(ll i=0;i<42;i++)for(ll j=0;j<=i;j++)if(i==j||j==0) C[i][j]=1;else C[i][j]=C[i-1][j-1]+C[i-1][j];}ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}ll cs(int k,int aa,int bb,int cc){int n=0;if(aa%k!=0) return 0;else {aa/=k;n+=aa;}if(bb%k!=0) return 0;else {bb/=k;n+=bb;}if(cc%k!=0) return 0;else {cc/=k;n+=cc;}return C[n][aa]*C[n-aa][bb]*C[n-aa-bb][cc];}ll solve(){ll s=a+b+c;ll ans=0;for(int i=0;i<s;i++)ans+=cs(s/gcd(s,i),a,b,c);if(s&1){if(a>=1) ans+=s*cs(2,a-1,b,c);if(b>=1) ans+=s*cs(2,a,b-1,c);if(c>=1) ans+=s*cs(2,a,b,c-1);}else{ans+=(s/2)*cs(2,a,b,c);if(a>=1&&b>=1) ans+=(s)*cs(2,a-1,b-1,c);if(b>=1&&c>=1) ans+=(s)*cs(2,a,b-1,c-1);if(c>=1&&a>=1) ans+=(s)*cs(2,a-1,b,c-1);if(a>=2) ans+=(s/2)*cs(2,a-2,b,c);if(b>=2) ans+=(s/2)*cs(2,a,b-2,c);if(c>=2) ans+=(s/2)*cs(2,a,b,c-2);}return ans/2/s;}int main(){int T;cin>>T;init();while(T--){scanf("%d%d%d",&a,&b,&c);printf("%lld\n",solve());}return 0;}



原创粉丝点击