• 【bzoj1004】[HNOI2008]Cards


    1004: [HNOI2008]Cards

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2928  Solved: 1754
    [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。

    【题解】

    染色法就相当于置换,要求的洗牌法就相当于等价类的个数。

    那么根据burnside定理,ans就是每种置换下不动点的数目的和除以m

    然而这道题关于颜色有限制,那么我们可以用f[i][j][k]表示用了i种颜色1,j种颜色2,k种颜色3的相同的方案数,b[h]表示循环节的长度,那么可以得到f[i][j][k]=f[i-d[h]][j][k]+f[i][j-d[h]][k]+f[i][j][k-d[h]]

    求出ans之后,由于计算出的ans是取模后的结果,然后要除以m,然后。。。乘法逆元解决。

    最后别忘了,除了题上给出的置换外,还有一个固定的置换,就是自身的置换。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<ctime>
     7 #include<algorithm>
     8 using namespace std;
     9 int sr,sb,sg,m,n,mod,ans,a[61][61],b[61],f[61][61][61],d[61];
    10 inline int read()
    11 {
    12     int x=0;char ch=getchar();
    13     while(ch<'0'||ch>'9')ch=getchar();
    14     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    15     return x;
    16 }
    17 int dp(int x)
    18 {
    19     for(int i=1;i<=n;i++)  b[i]=0;
    20     int sum=0,p=0;
    21     for(int i=1;i<=n;i++)
    22         if(!b[i])
    23         {
    24             p=i;  b[p]=1;  d[++sum]=1;
    25             while(!b[a[x][p]])
    26             {
    27                 b[a[x][p]]=1;
    28                 d[sum]++;
    29                 p=a[x][p];
    30             }
    31         }
    32     for(int i=sr;i>=0;i--)
    33         for(int j=sb;j>=0;j--)
    34             for(int k=sg;k>=0;k--)
    35                 f[i][j][k]=0;
    36     f[0][0][0]=1;
    37     for(int h=1;h<=sum;h++)
    38         for(int i=sr;i>=0;i--)
    39             for(int j=sb;j>=0;j--)
    40                 for(int k=sg;k>=0;k--)
    41                 {
    42                     if(i>=d[h])  f[i][j][k]=(f[i][j][k]+f[i-d[h]][j][k])%mod;
    43                     if(j>=d[h])  f[i][j][k]=(f[i][j][k]+f[i][j-d[h]][k])%mod;
    44                     if(k>=d[h])  f[i][j][k]=(f[i][j][k]+f[i][j][k-d[h]])%mod;
    45                 }
    46     return f[sr][sb][sg];
    47 }
    48 void exgcd(int a,int b,int &x,int &y)
    49 {
    50     if(b==0)  {x=1;  y=0;  return;}
    51     exgcd(b,a%b,x,y);
    52     int t=x;  x=y;  y=t-a/b*y;
    53 }
    54 int main()
    55 {
    56     sr=read();  sb=read();  sg=read();  m=read();  mod=read();
    57     n=sr+sb+sg;
    58     for(int i=1;i<=m;i++)
    59         for(int j=1;j<=n;j++)
    60             a[i][j]=read();
    61     m++;
    62     for(int i=1;i<=n;i++)  a[m][i]=i;
    63     for(int i=1;i<=m;i++)  ans=(ans+dp(i))%mod;
    64     int x,y;
    65     exgcd(m,mod,x,y);
    66     while(x<0)  x+=mod;
    67     printf("%d
    ",ans*x%mod);
    68     return 0;
    69 }
    View Code
  • 相关阅读:
    作为平台的Windows PowerShell(一)
    PowerShell中的数学计算
    PowerShell远程安装应用程序
    CRC码计算
    HTTP API 设计指南
    Restfull API 示例
    使用HttpClient 发送 GET、POST、PUT、Delete请求及文件上传
    函数可重入性及编写规范
    Python3中的http.client模块
    python用httplib模块发送get和post请求***
  • 原文地址:https://www.cnblogs.com/chty/p/5850380.html
Copyright © 2020-2023  润新知