ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【第二类斯特林数+容斥原理】Codeforces-140E. New Year Garland

2021-10-23 21:33:03  阅读:227  来源: 互联网

标签:种颜色 12 Garland int 容斥 colors Edward lamps Year


题目链接(https://codeforces.com/problemset/problem/140/E)

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 \(l_1\) lamps, the second layer — with the next \(l_2\) lamps and so on. The last n-th layer should be decorated with the last \(l_n\) lamps, img

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 \(n\), \(m\) and \(p\) \((1 ≤ n, m ≤ 10^6, 2 ≤ p ≤ 10^9)\) which are the number of the tree's layers, the number of the lamps' colors and module correspondingly. The next line contains \(n\) integers \(l_i\) (1 ≤ \(l_i\) ≤ 5000, img).

Output

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

Examples

input

3 2 1000
3 1 2

output

8

input

2 3 1000
2 2

output

24

input

1 1 1000
5

output

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:

img

题意

给一个n层能挂彩球的圣诞树(二维数组),每一层\(l[i]\)的大小固定,给定m种颜色,要求每一层的颜色集合不同,同一层相邻彩球颜色不同,问有多少种放法,结果对p取模

思路

一眼DP,但还是要一个个解决子问题

子问题一,先考虑第 \(i\) 层上能放多少种颜色,设\(f[i][j]\)表示长度为\(i\)的层放\(j\)种颜色的球的方案数:

这里的递推就是第二类斯特林数(懒得画图,语言来描述吧)

设某一层长度为\(n\),颜色数为\(k\)

如果前\(n-1\)个球只用了\(k-1\)种颜色,那么最后一个球肯定要用剩下的那\(1\)种颜色,那么这部分的方案数就包含上一步只含\(k-1\)种颜色的递推,\(f[l - 1][k - 1] * 1 = f[l - 1][k - 1]\),

如果前\(n-1\)个球已经用了\(k\)种颜色,那么最后一个球肯定要用与第\(l - 1\)个球不同的颜色,因为第\(l - 1\)个球可能有\(k\)种(都能涉及)颜色,第\(l\)个球只可能用与它不同的颜色,所以第\(l\)个球可能有\((k - 1)\)种颜色,那么这部分的方案数就包含上一步含\(k\)种颜色的递推\(f[l - 1][k] * (k - 1)\),

故\(f[i][j] = f[i−1][j−1] + f[i−1][j]∗(j−1)\)

长度为\(l[i]\),那么最多用的颜色可以是\(l[i]\),预处理长度为\(l[i]\)的一层最多能用多少种方案数,可以累加,即设\(s[l[i]] = f[l[i]][1] * C_m^1 * 1 ! + f[l[i]][2] * C_m^2 * 2 !+ ... + f[l[i]][l[i]] * C_m^i * i !\),这里累加预处理的复杂度是\(O(i ^ 2)\)

子问题二,因为本层和上一层的颜色集合不能是一致的,可以开一个新的动态规划,用 \(dp[i][j]\)表示第\(i\)层用 \(j\) 种颜色的合法方案数(前提,第\(1\)到\(i−1\)层合法)

那么,它的转移方程式\(dp[i][j]\)=\(f[l[i]][j] * (s[i - 1] - dp[i - 1][j] * j !)\)

(翻译:这层本身方案数 * (上一层方案数 - 之前存在刚好和本层颜色方案相同的情况))

得 \(s[i] = \sum_{j=1}^{l[i]} dp[i][j] * C_m ^ j * j !\),继续处理,\(C_m^i * i ! == m ^ \underline{i}\) \(==\)\(m^\underline{i - 1} *(m - i + 1)\)(可以预处理)

预处理后,最后一种的方案数\(s[n]\)即为答案,复杂度\(O(l ^ 2 + L)\)

AC代码

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define int long long
#define ull unsigned long long
#define PII pair<int,int>
using namespace std;
typedef long long LL;
const int N = 5e3 + 1;
const int mod = 1e9 + 7;
const double pi = acos(-1.0);
int T, n, m, p;
int l[N];
int f[N][N];//子问题一
int fact[N], C[N];//阶乘,组合数
vector<int> gra[N];//学别人的,全图开一个vector优化空间
int s[N];
//取模前可能会爆int,如果没有define int ll的习惯取模前还是要加上ll
//思路讲的贼清楚,可以对应上,就不逐字符注释了
void solve() {
	for (int i = 1; i <= n; i++) {
		cin >> l[i];
		gra[i].resize(l[i] + 1);
	}//初始化

	f[0][0] = 1;
	for (int i = 1; i < N; i++) {
		for (int j = 1; j <= i; j++) {
			f[i][j] = f[i - 1][j - 1] + 1LL * f[i - 1][j] * (j - 1) % p;
			if (f[i][j] >= p) {
				f[i][j] -= p;
			}
		}
	}//子问题一预处理

	fact[0] = 1; C[0] = 1;
	for (int i = 1; i < N; i++) {
		fact[i] = 1LL * fact[i - 1] * i % p;
	}//阶乘预处理

	for (int i = 1; i <= m && i < N; i++) {
		C[i] = 1LL * C[i - 1] * (m - i + 1) % p;
	}//组合数预处理
	s[0] = 1;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= l[i]; j++) {
			gra[i][j] = 1LL * s[i - 1] * f[l[i]][j] % p * C[j] % p;
			if (i > 1 && j <= l[i - 1]) {
				gra[i][j] -= 1LL * fact[j] * gra[i - 1][j] % p * f[l[i]][j] % p;
				if (gra[i][j] < 0) {
					gra[i][j] += p;
				}
			}
			s[i] += gra[i][j];
			if (s[i] >= p) {
				s[i] -= p;
			}
		}
	}
	cout << s[n] << endl;
	return;
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	while (cin >> n >> m >> p) {
		solve();
	}
	return 0;
}
/*
	i raised a cute kitty in my code,
	my friend who pass by can touch softly on her head:)

		 /l、
   Meow~(゚、 。7
		 |、 ~ヽ
		 じしf_,)ノ

*/

标签:种颜色,12,Garland,int,容斥,colors,Edward,lamps,Year
来源: https://www.cnblogs.com/peace0218/p/15449546.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有