BZOJ1004:[HNOI2008]Cards (Burnside引理+DP+Exgcd)
来源:互联网 发布:interbase数据库 编辑:程序博客网 时间:2024/06/05 08:40
题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1004
题目分析:最近我总是在省选题中找题目做,结果遇到各种奇奇怪怪的坑。
这题的题面告诉我们,如果某个状态可以通过一次洗牌到达另一种状态,就从这种状态向另一种状态连一条有向边,那么最终的图一定全部是双向边,并且所有的状态组成了一些团。团的个数即为答案。现在的问题是如何求出团的个数?
我自己的想法是用
然而这样显然超时,我想了很久,然后看了题解才知道这里要用到一个叫做Burnside引理的东西,它貌似和Polya定理有些关联。于是我果断%了一波网上dalao写的关于这个引理的学习笔记。虽然证明看得差不多了,但其实还有两个核心的地方不是很明白:同一个等价类的元素,Zi肯定是相同的,以及i的等价类的个数乘以令i不变化的置换的个数=置换的总个数。在此留一个坑,希望日后自己能来填或者有大神路过教导一下QAQ。
上述引理告诉我们:对于一个置换群,只要求出每一个置换的不动点个数,其平均值就是该群的本质不同的染色方案数。也就是说在这题中,我们只要对每一个洗牌方案算出有多少种状态,洗了之后还是它自身,加起来除以m+1即可。为什么是m+1呢?因为我们还要算上这个群的单位元——p[i]=i的置换,它对答案的贡献为
By the way,听说此题有人直接算原谅我不会证?难道题目有什么特殊保证而我没有看出来?总之本人是写了DP的。
CODE:
#include<iostream>#include<string>#include<cstring>#include<cmath>#include<cstdio>#include<cstdlib>#include<stdio.h>#include<algorithm>using namespace std;const int maxn=25;const int maxm=65;int f[maxn][maxn][maxn];int X,Y;int Size[maxm];int fa[maxm];int g[maxm][maxm];int a,b,c,m,p;int n;int Up(int x){ if (fa[x]==x) return x; return (fa[x]=Up(fa[x]));}void Add(int x,int y){ x=Up(x); y=Up(y); if (x==y) return; fa[x]=y; Size[y]+=Size[x];}void Exgcd(int a,int b){ if (!b) X=1,Y=0; else { Exgcd(b,a%b); int u=Y; int v=X-a/b*Y; X=u; Y=v; }}int main(){ freopen("1004.in","r",stdin); freopen("1004.out","w",stdout); scanf("%d%d%d%d%d",&a,&b,&c,&m,&p); n=a+b+c; for (int i=1; i<=m; i++) for (int j=1; j<=n; j++) scanf("%d",&g[i][j]); m++; for (int i=1; i<=n; i++) g[m][i]=i; int ans=0; for (int i=1; i<=m; i++) { for (int j=1; j<=n; j++) fa[j]=j,Size[j]=1; for (int j=1; j<=n; j++) Add(j,g[i][j]); for (int j=1; j<=n; j++) Up(j); memset(f,0,sizeof(f)); f[0][0][0]=1; for (int j=1; j<=n; j++) if (fa[j]==j) { int k=Size[j]; for (int x=a; x>=0; x--) for (int y=b; y>=0; y--) for (int z=c; z>=0; z--) { int &v=f[x][y][z]; if (x>=k) v=(v+f[x-k][y][z])%p; if (y>=k) v=(v+f[x][y-k][z])%p; if (z>=k) v=(v+f[x][y][z-k])%p; } } ans=(ans+f[a][b][c])%p; } Exgcd(p,m); while (Y<0) Y+=p; ans=(ans*Y)%p; printf("%d\n",ans); return 0;}
- BZOJ1004:[HNOI2008]Cards (Burnside引理+DP+Exgcd)
- [BZOJ1004][HNOI2008][Burnside引理][DP]Cards
- 【bzoj1004】[HNOI2008]Cards burnside引理+dp
- 【BZOJ1004】Cards(HNOI2008)-Burnside引理+DP+逆元
- [BZOJ1004][HNOI2008]Cards-Burnside引理
- 【BZOJ1004】【HNOI2008】Cards 群论 置换 burnside引理 背包DP
- BZOJ1004 Cards (burnside dp 扩展欧几里德)
- [BZOJ1004] [HNOI2008] Cards - 群论,Burnside引理,Polya定理
- bzoj1004: [HNOI2008]Cards [Burnside&Ploya+求逆元]
- 【Burnside定理/置换】[HNOI2008][HYSBZ/BZOJ1004]Cards
- BZOJ1004 [HNOI2008]Cards(置换群+dp)
- HNOI2008——cards(burnside引理+DP)
- 【BZOJ1004】【Burnside定理】【DP】【扩展欧几里徳】cards
- 【bzoj 1004】[HNOI2008]Cards(burnside 引理)
- kyeremal-bzoj1004-[HNOI2008]-cards-dp+polya
- Bzoj1004:[HNOI2008]Cards:置换群+dp
- 【BZOJ】【P1004】【HNOI2008】【Cards】【题解】【Burnside引理+dp】
- BZOJ 1004: [HNOI2008]Cards Burnside dp
- 如何抓取关机闹钟(Poweroff Alarm)相关log?
- 树莓派-wiringPi-GPIO
- 【Scikit-Learn 中文文档】使用 scikit-learn 介绍机器学习 | ApacheCN
- 多线程下载+断点续传+播放视频
- AngularJs实现购物车
- BZOJ1004:[HNOI2008]Cards (Burnside引理+DP+Exgcd)
- 自定义注解
- linux下操作mysql
- MVP加泛型,抽基类,解绑,多条目
- 关于Ijkitplayer配置
- 学习笔记——冒泡排序的优化
- 将H5网站转换成原生体验的App
- HDOJ Doing Homework again JAVA 1789
- Blog19@linux介绍selinux