记录编号 140952 评测结果 AAAAAAAAAA
题目名称 [HNOI 2008]Cards 最终得分 100
用户昵称 GravatarAsm.Def 是否通过 通过
代码语言 C++ 运行时间 0.004 s
提交时间 2014-11-26 23:03:23 内存使用 0.43 MiB
显示代码纯文本
/**************************************************************
    Problem: 1004
    User: 935671154
    Language: C++
    Result: Accepted
    Time:24 ms
    Memory:1396 kb
****************************************************************/
 
#include <iostream>
#include <cctype>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
inline void getd(int &x){
    char c = getchar();
    bool minus = 0;
    while(!isdigit(c) && c != '-')c = getchar();
    if(c == '-')minus = 1, c = getchar();
    x = c - '0';
    while(isdigit(c = getchar()))x = x * 10 + c - '0';
    if(minus)x = -x;
}
/*======================================================*/
inline void exgcd(int a, int b, int &x, int &y){
    if(!a){x = 0, y = 1; return;}
    exgcd(b % a, a, y, x);
    x -= b / a * y;
}
 
const int maxn = 63, maxk = 22;
int R, B, G, m, mod, ans, inv, n;
int p[maxn], loop[maxn], len;
int dp[maxn][maxk][maxk] = {0};
int fact[maxn];
 
inline void init(){
    getd(R), getd(B), getd(G), getd(m), getd(mod);
    n = R + B + G;
    int i;fact[0] = 1;
    for(i = 1;i <= n;++i) fact[i] = fact[i-1] * i % mod;
    int x, y, t; ans = fact[n];
    t = fact[R] * fact[B] * fact[G] % mod;
    exgcd(t, mod, x, y);
    ans = ans * x % mod;
    if(ans < 0) ans += mod;
    exgcd(m + 1, mod, x, y);
    inv = x < 0 ? x + mod : x;
}
 
inline void analy(){
    len = 0;
    bool used[maxn] = {0};
    int i, j, cnt;
    for(i = 1;i <= n;++i){
        if(!used[i]){
            used[i] = 1, cnt = 1, j = p[i];
            while(j != i){
                used[j] = 1; ++cnt;
                j = p[j];
            }
            loop[++len] = cnt;
        }
    }
}
 
inline int count(){
    int i, j, k, s = 0;
    dp[0][0][0] = 1;
    for(i = 1;i <= len;++i){
        s += loop[i];
        for(j = 0;j <= R;++j) for(k = 0;k <= B;++k){
            dp[i][j][k] = 0;
            if(j >= loop[i])dp[i][j][k] += dp[i-1][j-loop[i]][k];
            if(k >= loop[i])dp[i][j][k] += dp[i-1][j][k-loop[i]];
            if(s-i-j >= loop[i])dp[i][j][k] += dp[i-1][j][k];
            dp[i][j][k] %= mod;
        }
    }
    return dp[len][R][B] % mod;
}
 
inline void work(){
    int i;
    while(m--){
        for(i = 1;i <= n;++i) getd(p[i]);
        analy();
        ans = (ans + count()) % mod;
    }
    printf("%d\n", ans * inv % mod);
}
 
int main(){
    #if defined DEBUG
    freopen("test", "r", stdin);
	#else
	freopen("hnoi_cards.in", "r", stdin);
	freopen("hnoi_cards.out", "w", stdout);
    #endif
	
    init();
	
    work();
	
    #if defined DEBUG
    cout << endl << (double)clock()/CLOCKS_PER_SEC << endl;
    #endif
    return 0;
}