UVA - 11255 Necklace (poolya计数+组合数学)
2017-11-23 15:37
316 查看
题目链接:https://cn.vjudge.net/problem/UVA-11255
对polya和Burnside不做过多描述
类似于那道有限制的魔方置换,
首先算出环的所有
对于旋转有
对于翻转
考虑奇偶
当点为奇数时选取每个点与中心的连线作为对称轴,一共有n条
只需考虑一个点然后结果乘n就可以了
当选定一条对称轴,对称轴上的点自己构成一个循环
其他n-1个点两两构成循环,则一共有(n-1)/2+1个循环,其中一个长度为1(对称轴上的点),剩余(n-1)/2长度为2
当点数为偶数时
考虑选相对两点或者相邻两点的中点与其对应点构成的直线作为对称轴
当选择相对两点:
有(n/2)种选择方法,每种有(n-2)/2+2个循环,其中两个长度为2(对称轴上的两点),剩余(n-2)/2个长度为2;
当相邻两点的中点与其对应点:
有(n/2)种,每种n/2个循环,长度均为2;
最后考虑填色
因为每个循环中各个点颜色都一样,可以考虑枚举特殊点(如果有特殊点的话,比如自己构成循环的一个点),其他点利用乘法原理和组合数即可算出
相当与讲n个球放入n个箱子,每个循环就是一个限制条件。
对polya和Burnside不做过多描述
类似于那道有限制的魔方置换,
首先算出环的所有
对于旋转有
对于翻转
考虑奇偶
当点为奇数时选取每个点与中心的连线作为对称轴,一共有n条
只需考虑一个点然后结果乘n就可以了
当选定一条对称轴,对称轴上的点自己构成一个循环
其他n-1个点两两构成循环,则一共有(n-1)/2+1个循环,其中一个长度为1(对称轴上的点),剩余(n-1)/2长度为2
当点数为偶数时
考虑选相对两点或者相邻两点的中点与其对应点构成的直线作为对称轴
当选择相对两点:
有(n/2)种选择方法,每种有(n-2)/2+2个循环,其中两个长度为2(对称轴上的两点),剩余(n-2)/2个长度为2;
当相邻两点的中点与其对应点:
有(n/2)种,每种n/2个循环,长度均为2;
最后考虑填色
因为每个循环中各个点颜色都一样,可以考虑枚举特殊点(如果有特殊点的话,比如自己构成循环的一个点),其他点利用乘法原理和组合数即可算出
相当与讲n个球放入n个箱子,每个循环就是一个限制条件。
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <algorithm> #include <string.h> #include <math.h> #include <vector> #include <set> #include <map> #include <queue> #include <stack> #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long #define ull unsigned long long #define EPS 1e-8 #define IOS ios_base::sync_with_stdio(0); cin.tie(0) using namespace std; typedef pair<int,int> pii; typedef pair<long,long> pll; const double pi = acos(-1.0); inline ll read() { ll x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return f*x; } ll c[45][45]; int a[5],b[5],t,tot; int gcd(int x,int y) { return y?gcd(y,x%y):x; } void init()//预处理组合数 { for(int i=0;i<=40;i++) { c[i][0]=c[i][i]=1; for(int j=1;j<i;j++) { c[i][j]=c[i-1][j]+c[i-1][j-1]; } } } ll cal(int k)//k代表循环的长度 { ll res=1LL; int cnt=0; for(int i=0;i<3;i++) { if(b[i]%k==0) { b[i]/=k; cnt+=b[i]; } else { return 0; } } for(int i=0;i<3;i++) { res*=c[cnt][b[i]]; cnt-=b[i]; } return res; } ll rotation() { ll res=0; for(int i=1;i<=tot;i++) { memcpy(b,a,sizeof(a)); res+=cal(tot/gcd(i,tot)); } return res; } ll filpping() { ll res=0; if(tot&1) { for(int i=0;i<3;i++)//逐个处理自己构成循环的点的颜色 { memcpy(b,a,sizeof(a)); b[i]--; if(b[i]<0) { continue; } res+=(ll)tot*cal(2); } } else { for(int i=0;i<3;i++)//有两个点会独自构成循环 { for(int j=0;j<3;j++) { memcpy(b,a,sizeof(a)); b[i]--; b[j]--; if(b[i]<0||b[j]<0) { continue; } res+=(ll)(tot/2)*cal(2); } } memcpy(b,a,sizeof(a)); res+=(ll)(tot/2)*cal(2); } return res; } ll polya() { ll res=0; res+=rotation(); res+=filpping(); return res/(2*tot);//注意置换数为2*tot } int main() { #ifdef TEST freopen("input.txt","r",stdin); #endif init(); scanf("%d",&t); while(t--) { tot=0; for(int i=0;i<3;i++) { scanf("%d",a+i); tot+=a[i]; } printf("%lld\n",polya()); } return 0; }
相关文章推荐
- Necklace UVA - 11255
- UVA 11255 Necklace(Polya)
- UVA11255 necklace (polya定理)
- UVA 11255 Necklace(每种颜色珠子个数限制、Polya原理、组合数)
- UVA 11255 - Necklace (等价置换)
- uva11255 Necklace(polya+组合数学)
- UVA - 11255 Necklace 母函数型polya
- UVA 11255 Necklace
- uva11255 - Necklace 项链旋转翻转 置换
- UVA 11255 Necklace
- uva 11255 Necklace
- UVA 11255 Necklace(Burnside引理)
- Necklace UVA - 11255(polya计数)
- UVA 11255 - Necklace(Ploya)
- uva 11255 Necklace (polya)
- uva 11255 - Necklace(置换)
- UVa 10054 The Necklace(欧拉回路)
- UVa 10054 : The Necklace 【欧拉回路】
- The Necklace UVA10054
- UVa 10054 - The Necklace