zoukankan      html  css  js  c++  java
  • BZOJ 1004 [HNOI2008]Cards

    1004: [HNOI2008]Cards

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2163  Solved: 1286
    [Submit][Status][Discuss]

    Description

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

    Input

    第一行输入 5 个整数:Sr,Sb,Sg,m,p(m<=60,m+1<p<100)。n=Sr+Sb+Sg。接下来 m 行,每行描述
    一种洗牌法,每行有 n 个用空格隔开的整数 X1X2...Xn,恰为 1 到 n 的一个排列,表示使用这种洗牌法,
    第 i位变为原来的 Xi位的牌。输入数据保证任意多次洗牌都可用这 m种洗牌法中的一种代替,且对每种
    洗牌法,都存在一种洗牌法使得能回到原状态。

    Output

    不同染法除以P的余数

    Sample Input

    1 1 1 2 7
    2 3 1
    3 1 2

    Sample Output

    2

    HINT

    有2 种本质上不同的染色法RGB 和RBG,使用洗牌法231 一次可得GBR 和BGR,使用洗牌法312 一次 可得BRG 和GRB。

    100%数据满足 Max{Sr,Sb,Sg}<=20。

    Source

    题解:妈妈呀我会置换群了!快膜cyx!!!

    Burnside定理:有m个置换k中颜色,所有本质不同的染色方案数就是每种置换的不变元素的个数的平均数。所谓不变元素就是一种染色方案经过置换变换后和没变化之前一样。所以现在就是需要求出不变元素,同时还要满足各种颜色数量的限制。置换的循环在不变元素中一定是一个颜色,然后可以求一个三维的01背包的方案数。最后再写个逆元就好。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<cstring>
     7 #define PAU putchar(' ')
     8 #define ENT putchar('
    ')
     9 using namespace std;
    10 const int maxn=100+10,maxm=20+5,inf=-1u>>1;
    11 int z[maxn],s[maxn],f[maxm][maxm][maxm],scnt,sr,sg,sb,m,mod,n;bool vis[maxn];
    12 void add(int&a,int b){a=(a+b)%mod;}
    13 int calc(){
    14     memset(f,0,sizeof(f));
    15     memset(vis,false,sizeof(vis));
    16     memset(s,0,sizeof(s));
    17     scnt=0;
    18     for(int i=1;i<=n;i++) if(!vis[i]){
    19         scnt++;for(int j=i;!vis[j];j=z[j])vis[j]=true,s[scnt]++;
    20     }f[0][0][0]=1;
    21     for(int i=1;i<=scnt;i++)
    22         for(int r=sr;r>=0;r--)
    23         for(int g=sg;g>=0;g--)
    24         for(int b=sb;b>=0;b--){
    25             if(r>=s[i])add(f[r][g][b],f[r-s[i]][g][b]);
    26             if(g>=s[i])add(f[r][g][b],f[r][g-s[i]][b]);
    27             if(b>=s[i])add(f[r][g][b],f[r][g][b-s[i]]);
    28         }
    29     return f[sr][sg][sb];
    30 }
    31 void exgcd(int a,int b,int&x,int&y){
    32     if(b==0){x=1;y=0;return;}exgcd(b,a%b,x,y);int t=x;x=y;y=t-a/b*y;
    33 }
    34 int ine(int T){
    35     int x,y;exgcd(T,mod,x,y);x%=mod;while(x<=0)x+=mod;return x;
    36 }
    37 inline int read(){
    38     int x=0,sig=1;char ch=getchar();
    39     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
    40     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
    41     return x*=sig;
    42 }
    43 inline void write(int x){
    44     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
    45     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
    46     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
    47 }
    48 void init(){
    49     sr=read();sg=read();sb=read();m=read();mod=read();
    50     n=sr+sg+sb;int ans=0;
    51     for(int time=1;time<=m;time++){
    52         for(int i=1;i<=n;i++)z[i]=read();
    53         add(ans,calc());
    54     }
    55     for(int i=1;i<=n;i++)z[i]=i;
    56     add(ans,calc());write(ans*ine(m+1)%mod);
    57     return;
    58 }
    59 void work(){
    60     return;
    61 }
    62 void print(){
    63     return;
    64 }
    65 int main(){init();work();print();return 0;}
  • 相关阅读:
    Android&Java面试题大全—金九银十面试必备
    android招聘啦,美图秀秀欢迎你加入!
    android经典源码,很不错的开源框架
    MongoDB、Hbase、Redis等NoSQL优劣势、应用场景
    体验go语言的风骚式编程
    金九银十中,看看这31道Android面试题
    android高级页面效果集锦
    flask中的request
    flask笔记(三)Flask 添加登陆验证装饰器报错,及解析
    flask笔记(二)
  • 原文地址:https://www.cnblogs.com/chxer/p/4639153.html
Copyright © 2011-2022 走看看