1. 程式人生 > >[HNOI2008]Cards

[HNOI2008]Cards

pan noi long 輪換 bsp include hnoi2008 使用 正確答案

題目描述

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

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

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

SOL:

輸入數據保證任意多次洗牌都可用這 m種洗牌法中的一種代替,且對每種

洗牌法,都存在一種洗牌法使得能回到原狀態。

所以每一種置換都是幾個大小非1輪換的乘積。(若有1的話,那麽就不能同時達到兩個條件了,這是顯然的)

所以沒有一個置換(除原置換外)有不動點。

所以根據burnside引理,答案就是(a+b+c)!/(a!*b!*c!*(m+1))

而且保證p為質數,就省得打孫子剩余定理了,只要費馬小定理就ok。

#include<bits/stdc++.h>
#define LL long long
#define N 123
using namespace std;
int a,b,c,d,e,fac[N],ni[N],T,answ;
LL qsm(LL x,LL y){
    LL ans
=1; while (y) { if (y&1) (ans*=x)%=e; y>>=1; (x*=x)%=e; } return ans; } int main () { scanf("%d%d%d%d%d",&a,&b,&c,&d,&e);//不用讀完所有的數據 fac[0]=1;T=a+b+c; for (int i=1;i<=T;i++) fac[i]=fac[i-1]*i%e; ni[T]=qsm(fac[T],e-2); for (int
i=T;i ;i--) ni[i-1]=ni[i]*i%e; answ=fac[T]*ni[a]%e*ni[b]%e*ni[c]%e*qsm(d+1,e-2)%e; printf("%d",answ); }

[HNOI2008]Cards