[BZOJ1004] [HNOI2008]Cards解题报告(Burnside引理)

Description

  小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Sun有多少种染色方案,Sun很快就给出了答案.进一步,小春要求染出Sr张红色,Sb张蓝色,Sg张绝色.他又询问有多少种方案,Sun想了一下,又给出了正确答案. 最后小春发明了M种不同的洗牌法,这里他又问Sun有多少种不同的染色方案.两种染色方法相同当且仅当其中一种可以通过任意的洗牌法(即可以使用多种洗牌法,而每种方法可以使用多次)洗成另一种.Sun发现这个问题有点难度,决定交给你,答案可能很大,只要求出答案除以P的余数(P为质数).  

    这道题做了挺久的...感觉还是对于Burnside引理理解的不够透彻吧。

    Burnside引理:

      L=1/|G|*(c1+c2+...ck),ci表示第i种置换的不动置换类。如置换:(123)(45)(6)中的不动置换类只有(6)一个。

    这道题不能用Polya定理,因为每种颜色有具体的数量要求,不能任意染色。

    题目中给的洗牌方法,很显然就是一个个置换了。那么不动置换类要怎么求呢?

    颜色相同的看上去也一样,所以如果置换后位置上的颜色与原位置的颜色相同,也算是不动置换类

    而这道题需要思考的是,我们应该怎样把染色方案带到公式里去。

    答案是,将一个染色方案看做一个元素。

    即这道题中的不动置换类为经过该种置换后仍然不变的一个染色方案。

    那么不动置换类的个数即ci也就是满足在经过i种置换后每一位上颜色都不变的染色方案总数。

    则每个循环中要染同一种颜色,可以用01背包来计算方案数。

    最后不能忘记最重要也是最基础的一个置换即(1)(2)(3)...(n)这个置换。

    实现的过程中需要用到求乘法逆元。稍加注意即可。

     

program bzoj1004;
const maxn=65;
var i,j,t1,t2,t3:longint;
    s1,s2,s3,m,p,n,ans,tot,sum,x:int64;
    f:array[-1..maxn,-1..maxn,-1..maxn]of int64;
    vis:array[-1..maxn]of boolean;
    a:array[-1..maxn]of longint;

function ex_Euclid(a,b:int64;var x,y:int64):int64;
var t:int64;
begin
    if b=0 then
    begin
        x:=1;y:=0;exit(a);
    end else
    begin
        ex_Euclid:=ex_Euclid(b,a mod b,x,y);
        t:=x;x:=y;y:=t-(a div b)*y;
    end;
end;

function inverse(a:int64):int64;
var x,y,tem,d:int64;
begin
    d:=ex_Euclid(a,p,x,y);
    if d<>1 then exit(-1) else
    begin
        if x<0 then
        begin
            tem:=(-x) div p;
            x:=x+tem*p;y:=y-tem*a;
        end;
        if x<0 then
        begin
            x:=x+p;y:=y-p;
        end;
    end;
    exit(x);
end;

begin
    readln(s1,s2,s3,m,p);n:=s1+s2+s3;
    ans:=1;
    for i:=2 to n do ans:=(ans*i) mod p;
    for i:=2 to s1 do ans:=(ans*inverse(i)) mod p;
    for i:=2 to s2 do ans:=(ans*inverse(i)) mod p;
    for i:=2 to s3 do ans:=(ans*inverse(i)) mod p;
        for i:=1 to m do
    begin
        fillchar(f,sizeof(f),0);
        fillchar(vis,sizeof(vis),true);
        f[0,0,0]:=1;sum:=0;
        for j:=1 to n do read(a[j]);readln;
        for j:=1 to n do if vis[j] then
        begin
            tot:=0;
            x:=a[j];vis[j]:=false;
            while x<>j do
            begin
                inc(tot);
                vis[x]:=false;
                x:=a[x];
            end;
            inc(sum,tot);
            for t1:=0 to sum do
                for t2:=0 to sum-t1 do
                begin
                    t3:=sum-t1-t2;
                    if t1-tot>=0 then f[t1,t2,t3]:=(f[t1,t2,t3]+f[t1-tot,t2,t3]) mod p;
                    if t2-tot>=0 then f[t1,t2,t3]:=(f[t1,t2,t3]+f[t1,t2-tot,t3]) mod p;
                    if t3-tot>=0 then f[t1,t2,t3]:=(f[t1,t2,t3]+f[t1,t2,t3-tot]) mod p;
                end;
        end;
    end;
    ans:=(ans*inverse(m+1)) mod p;
    writeln(ans);
end.

 

      

时间: 2024-11-05 06:04:52

[BZOJ1004] [HNOI2008]Cards解题报告(Burnside引理)的相关文章

bzoj1004: [HNOI2008]Cards Burnside引理+01背包

三维01背包算出在每一个置换下不变的染色方案数,Burnside引理计算答案. PS:数据太水所以只算恒等置换也是可以过的. #include<bits/stdc++.h> using namespace std; int n,m,p,x,y,z; bool u[61]; int f[21][21][21],s[61],v[61]; int power(int u,int v){ int d=1; for(;v;v>>=1){ if(v&1) d=d*u%p; u=u*u%

bzoj1004: [HNOI2008]Cards(burnside引理+DP)

题目大意:3种颜色,每种染si个,有m个置换,求所有本质不同的染色方案数. 置换群的burnside引理,还有个Pólya过几天再看看... burnside引理:有m个置换k种颜色,所有本质不同的染色方案数就是每种置换的不变元素的个数的平均数. 求每种置换的不变元素的个数用背包解决.因为置换之后元素不变,所以对于每个循环节我们要染一个颜色,于是先处理出循环节作为背包中的"物体",然后一个三维背包解决.f[i][j][k]的i j k表示三种颜色分别还可以染多少次. 除m%p用费马小定

[bzoj1004][HNOI2008][Cards] (置换群+Burnside引理+动态规划)

Description 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Sun有多少种染色方案,Sun很快就给出了答案.进一步,小春要求染出Sr张红色,Sb张蓝色,Sg张绝色.他又询问有多少种方案,Sun想了一下,又给出了正确答案. 最后小春发明了M种不同的洗牌法,这里他又问Sun有多少种不同的染色方案.两种染色方法相同当且仅当其中一种可以通过任意的洗牌法(即可以使用多种洗牌法,而每种方法可以使用多次)洗成另一种.Sun发现这个问题有点难度,决

BZOJ1004 [HNOI2008]Cards

本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/转载请注明出处,侵权必究,保留最终解释权! 题目链接:BZOJ1004 正解:$Burnside$引理 解题报告: 经典$Burnside$引理题. 考虑一般的$Burnside$引理题都是直接求出一阶循环的个数,然后对于置换个数取平均数. 但是有颜色限制,所以我们不能直接算. 而因为一个洗牌方案相

[BZOJ1004] [HNOI2008] Cards (Polya定理)

Description 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Sun有多少种染色方案,Sun很快就给出了答案.进一步,小春要求染出Sr张红色,Sb张蓝色,Sg张绝色.他又询问有多少种方案,Sun想了一下,又给出了正确答案. 最后小春发明了M种不同的洗牌法,这里他又问Sun有多少种不同的染色方案.两种染色方法相同当且仅当其中一种可以通过任意的洗牌法(即可以使用多种洗牌法,而每种方法可以使用多次)洗成另一种.Sun发现这个问题有点难度,决

[BZOJ1004][HNOI2008]Cards 群论+置换群+DP

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1004 首先贴几个群论相关定义和引理. 群:G是一个集合,*是定义在这个集合上的一个运算. 如果满足以下性质,那么(G, *)是一个群. 1)封闭性,对于任意 a, b 属于 G, a * b 属于 G 2)结合律, a * b * c = a * (b * c) 3)单位元,在 G 中存在一个单位元 e ,使得对于 G 中任意的 a , a * e = e * a = a 4)逆元, 对

BZOJ1004 [HNOI2008]Cards 【burnside定理 + 01背包】

题目链接 BZOJ1004 题解 burnside定理 在\(m\)个置换下本质不同的染色方案数,等于每种置换下不变的方案数的平均数 记\(L\)为本质不同的染色方案数,\(m\)为置换数,\(f(i)\)为置换\(i\)下不变的方案数,那么 \[L = \frac{1}{m}\sum\limits_{i = 1}^{m} f(i)\] 在一个置换下一个方案不变,当且仅当该置换的任意一个循环节内部颜色相同 记循环节个数为\(c_i\),色数为\(k\)且不限使用,那么该置换下不变的方案数为 \[

BZOJ1004 [HNOI2008]Cards(Polya计数)

枚举每个置换,求在每个置换下着色不变的方法数,先求出每个循环的大小,再动态规划求得使用给定的颜色时对应的方法数. dp[i][j][k]表示处理到当前圈时R,B,G使用量为i,j,k时的方法数,背包思想. #include<cstdio> #include<iostream> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #includ

【BZOJ1004】[HNOI2008]Cards Burnside引理

[BZOJ1004][HNOI2008]Cards 题意:把$n$张牌染成$a,b,c$,3种颜色.其中颜色为$a,b,c$的牌的数量分别为$sa,sb,sc$.并且给出$m$个置换,保证这$m$个置换加上本身的置换能构成一个置换群,两种染色方案被认为是相同的当且仅当一种方案可以通过某个置换变成另一种.求不同的染色方案数.答案对$P$取模. $sa,sb,sc\le 20,m\le 60$ 题解:这里对每种颜色都有一个限制,怎么办呢? 回顾从Burnside引理到Pólya定理的推导过程. 如果