Codeforces Round #100E. New Year Garland【DP】

E. New Year Garland

time limit per test

5 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

As Gerald, Alexander, Sergey and Gennady are already busy with the usual New Year chores, Edward hastily decorates the New Year Tree. And any decent New Year Tree must be decorated with a good garland. Edward has lamps of m colors and he wants to make a garland from them. That garland should represent a sequence whose length equals L. Edward's tree is n layers high and Edward plans to hang the garland so as to decorate the first layer with the first l1 lamps, the second layer — with the next l2 lamps and so on. The last n-th layer should be decorated with the last ln lamps, 

Edward adores all sorts of math puzzles, so he suddenly wondered: how many different ways to assemble the garland are there given that the both following two conditions are met:

  1. Any two lamps that follow consecutively in the same layer should have different colors.
  2. The sets of used colors in every two neighbouring layers must be different. We consider unordered sets (not multisets), where every color occurs no more than once. So the number of lamps of particular color does not matter.

Help Edward find the answer to this nagging problem or else he won't manage to decorate the Tree by New Year. You may consider that Edward has an unlimited number of lamps of each of m colors and it is not obligatory to use all m colors. The garlands are considered different if they differ in at least one position when represented as sequences. Calculate the answer modulo p.

Input

The first line contains three integers nm and p (1 ≤ n, m ≤ 106, 2 ≤ p ≤ 109) which are the number of the tree's layers, the number of the lamps' colors and module correspondingly. The next line contains n integers li (1 ≤ li ≤ 5000, ).

Output

Print the only integer — the number of garlands modulo p.

Examples

input

Copy

3 2 1000
3 1 2

output

Copy

8

input

Copy

2 3 1000
2 2

output

Copy

24

input

Copy

1 1 1000
5

output

Copy

0

Note

In the first sample the following variants are possible: 121|1|12, 121|1|21, 121|2|12, 121|2|21, 212|1|12, 212|1|21, 212|2|12, 212|2|21. In the second sample the following variants are possible: 12|13, 12|23, 12|31, 12|32 and so on.

Figure for the first sample:

分析:为了使问题便于分析,我们首先考虑单独一排。

对于每一排,我们可以用f[i][j]表示对于前i个球,恰好用j种颜色,每种颜色不相邻的方案数。这里我们不考虑颜色的排列,即相当于对前i个球的颜色种类进行划分,保证每个相邻的球不在同一个集合里面,且默认这些集合是没有区别的。

那么f[i][j]=f[i-1][j-1]+(j-1)*f[i-1][j](类似于第二类斯特林数)

那么在乘上一个j的排列就是总的方案数。

现在再来,我们假设相邻两排的约束条件是不存在的,用dp[i][j]表示1到i-1排已经放好,第i排恰好用j种颜色的方案数

那么dp[i][j]=(\sum _{k=1}^{min(l[i-1],m)}dp[i-1][k])*C_{m}^j*j!*f[l_i][j]

其中(\sum _{k=1}^{min(l[i-1],m)}dp[i-1][k])*C_{m}^j表示选颜色集合的方案。

OK,现在再来考虑题目中约束条件,在第i排选了j种颜色,一定会与第i-1排选j种颜色进行冲突,那么会冲突多少次呢?

dp[i-1][j]即使冲突的次数,那么我们在选颜色集合的时候将这一部分剪掉即可。

dp[i][j]=((\sum _{k=1}^{min(l[i-1],m)}dp[i-1][k])*C_{m}^j-dp[i-1][j])*j!*f[l_i][j]

最后滚动数组优化一下空间即可,组合数和排列都可以预处理出来。复杂度为O(L)

#include "bits/stdc++.h"

using namespace std;
long long n, m, mod;
long long a[1000004];
long long ans[1000004];
long long dp[2][1000004];
long long f[5004][5004];
long long fac[1000004];
long long A[1000004];

void init() {
    fac[0] = 1;
    for (int i = 1; i < 1000004; ++i) {
        fac[i] = i * fac[i - 1] % mod;
    }
    A[0] = 1;
    for (int i = 1; i <= m; ++i) {
        A[i] = A[i - 1] * (m - i + 1) % mod;
    }
}

int main() {
    cin >> n >> m >> mod;
    init();
    for (int i = 1; i <= n; ++i) {
        scanf("%lld", &a[i]);
    }
    memset(f, 0, sizeof(f));
    memset(dp, 0, sizeof(dp));
    memset(ans, 0, sizeof(ans));
    f[0][0] = 1;
    for (int i = 1; i <= 5000; ++i) {
        for (int j = 1; j <= 5000; ++j) {
            f[i][j] = (f[i - 1][j - 1] + f[i - 1][j] * (j - 1) % mod) % mod;
        }
    }
    ans[1] = 1;
    int now = 0;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= min(a[i], m); ++j) {
            dp[now][j] = ans[now ^ 1] * A[j] % mod * f[a[i]][j] % mod;
            if(j<=a[i-1])dp[now][j] = (dp[now][j] - dp[now ^ 1][j] * fac[j] % mod * f[a[i]][j] % mod + mod) % mod;
            ans[now] = (ans[now] + dp[now][j]) % mod;
        }
        now ^= 1;
        ans[now] = 0;
    }
    cout << ans[now ^ 1] << endl;
}

猜你喜欢

转载自blog.csdn.net/qq_42671946/article/details/90045326