1. 程式人生 > >洛谷 P1446 [HNOI2008]Cards 解題報告

洛谷 P1446 [HNOI2008]Cards 解題報告

P1446 [HNOI2008]Cards

題目描述

小春現在很清閒,面對書桌上的\(N\)張牌,他決定給每張染色,目前小春只有\(3\)種顏色:紅色,藍色,綠色.他詢問Sun有多少種染色方案,Sun很快就給出了答案.

進一步,小春要求染出\(S_r\)張紅色,\(S_b\)張藍色,\(S_g\)張綠色.他又詢問有多少種方案,Sun想了一下,又給出了正確答案. 最後小春發明了\(M\)種不同的洗牌法,這裡他又問Sun有多少種不同的染色方案.兩種染色方法相同當且僅當其中一種可以通過任意的洗牌法(即可以使用多種洗牌法,而每種方法可以使用多次)洗成另一種.

Sun發現這個問題有點難度,決定交給你,答案可能很大,只要求出答案除以\(P\)

的餘數(\(P\)為質數).

輸入輸出格式

輸入格式:

第一行輸入 \(5\) 個整數:\(S_r,S_b,S_g,m,p(m\le 60,m+1<p<100)\)\(n=S_r+S_b+S_g\)。接下來 \(m\) 行,每行描述一種洗牌法,每行有 \(n\) 個用空格隔開的整數 \(X_1X_2\dots X_n\),恰為 \(1\)\(n\) 的一個排列,表示使用這種洗牌法,第 \(i\) 位變為原來的 \(X_i\) 位的牌。輸入資料保證任意多次洗牌都可用這 \(m\) 種洗牌法中的一種代替,且對每種洗牌法,都存在一種洗牌法使得能回到原狀態。

\(100\%\)資料滿足 \(\max\{S_r,S_b,S_g\}\le 20\)

輸出格式:

不同染法除以\(P\)的餘數


其實這個題的\(DP\)做法應該就是官方正解了,思維難度並不高。

很顯然是變換構成了一個群

考慮\(polya\)定理

\[\frac{1}{|G|}\sum_{\pi \in G}m^{w(\pi)}\]

然後因為每個迴圈節同色,我們可以直接求迴圈節然後\(dp\)

注意單位元不給,要自己加上

還有一種比較神奇的做法,發現這個題還給了除群外的一個性質,然後可以得到一個結論,僅單位元有不動點,然後\(Burnside\)直接組合算就可以了,答案就是

\[\frac{(a+b+c)!}{a!b!c!(m+1)}\]

然後我並不會證,比較嚴謹的描述如下,如果誰可以給出證明,煩請私信我一下啦

\(G=\{\pi_1,\pi_2,\dots,\pi_p\}\)是目標集\([1,n]\)上的置換群,且\(\forall t=\sum \pi_k,\pi_k \in G\),定義\(\sum\)為置換的連線操作,且\(k\)可重,\(\exists t \in G\),求證僅\(G\)的單位元存在不動點。


Code:

#include <cstdio>
const int N=201;
#define mul(a,b) (1ll*(a)*(b)%mod)
int a,b,c,m,mod,fac[N];
int qp(int d,int k){int f=1;while(k){if(k&1)f=mul(f,d);d=mul(d,d);k>>=1;}return f;}
int main()
{
    scanf("%d%d%d%d%d",&a,&b,&c,&m,&mod);
    for(int x,i=1;i<=m;i++)
        for(int j=1;j<=a+b+c;j++)
            scanf("%d",&x);
    fac[0]=1;
    for(int i=1;i<=N;i++) fac[i]=mul(fac[i-1],i);
    int ans=mul(fac[a+b+c],mul(qp(fac[a],mod-2),mul(qp(fac[b],mod-2),mul(qp(fac[c],mod-2),qp(m+1,mod-2)))));
    printf("%d\n",ans);
    return 0;
}

2018.12.21