UVA 11255 Necklace

时间:2022-10-13 10:23:01

带颜色数限制的polya计数。

其实感觉一样了。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 50
using namespace std;
long long t,col[],c[maxn][maxn],n;
long long gcd(long long a,long long b)
{
if (!b) return a;
return gcd(b,a%b);
}
void get_table()
{
c[][]=;
for (long long i=;i<=;i++)
{
c[i][]=;
for (long long j=;j<=;j++)
c[i][j]=c[i-][j-]+c[i-][j];
}
}
long long circ()
{
long long ret=;
for (long long i=;i<n;i++)
{
long long d=gcd(i,n),x=n/d,base=;
if ((col[]%(n/d)) || (col[]%(n/d)) || (col[]%(n/d))) continue;
for (long long j=;j<=;j++)
{
base*=c[d][col[j]/x];
d-=col[j]/x;
}
ret+=base;
}
return ret;
}
long long reflect()
{
long long ret=,ret1=,ret2=;
if (n&)
{
long long cols[];
if ((col[]&) && (col[]&) && (col[]&)) return ;
for (long long i=;i<=;i++) {cols[i]=col[i];if (cols[i]&) cols[i]--;}
long long sum=n/;
for (long long i=;i<=;i++)
{
ret*=c[sum][cols[i]/];
sum-=cols[i]/;
}
return ret*n;
}
else
{
long long cnt=,cols[];
for (long long i=;i<=;i++) {cnt+=(col[i]&);cols[i]=col[i];}
if (cnt==)
{
for (long long i=;i<=;i++) if (cols[i]&) cols[i]--;
long long sum=(n-)/;
for (long long i=;i<=;i++)
{
ret1*=c[sum][cols[i]/];
sum-=cols[i]/;
}
ret1*=(n/);ret1*=;
}
else
{
ret1=;
for (long long i=;i<=;i++)
{
long long base=,cols[],sum=(n-)/;
for (long long j=;j<=;j++) cols[j]=col[j];
cols[i]-=;
for (long long j=;j<=;j++)
{
base*=c[sum][cols[j]/];
sum-=cols[j]/;
}
ret1+=base;
}
ret1*=(n/);
}
if (!cnt)
{
long long sum=n/;
for (long long i=;i<=;i++)
{
ret2*=c[sum][cols[i]/];
sum-=cols[i]/;
}
ret2*=(n/);
}
else ret2=;
return ret1+ret2;
}
}
void work()
{
scanf("%lld%lld%lld",&col[],&col[],&col[]);
n=col[]+col[]+col[];
printf("%lld\n",(circ()+reflect())/(*(col[]+col[]+col[])));
}
int main()
{
get_table();
scanf("%lld",&t);
for (long long i=;i<=t;i++) work();
return ;
}