CodeForces 1838E Count Supersequences

洛谷传送门

CF 传送门

结论:\(a_i\) 对答案没有影响。

考虑设计一个 \(O(nm)\) dp,\(f_{i, j}\) 表示填到第 \(i\) 个位置,匹配到了 \(a\) 的第 \(j\) 个位置。发现无论 \(a_j\) 是什么,总是恰好有 \(1\)\(1 \sim k\) 的数,满足填了它之后 \(j\)\(1\),恰好有 \(k - 1\) 个数,满足填了它后 \(j\) 不改变。

既然跟 \(a_i\) 是什么无关,就不妨让 \(a_i = 1\),可以转化成,计数长度为 \(m\),值域 \([1, k]\),至少有 \(n\)\(1\) 的序列。这个计数是平凡的,容斥,变成 \(1\) 的个数 \(< n\)。枚举 \(1\) 的个数即可,答案为:

\[k^m - \sum\limits_{i = 0}^{n - 1} \binom{m}{i} (k - 1)^{m - i} \]

注意这题不能预处理阶乘及其逆元,但是 \(\binom{m}{i}\) 是可以通过 \(\binom{m}{i - 1}\) 递推得到的。

code
// Problem: E. Count Supersequences
// Contest: Codeforces - Codeforces Round 877 (Div. 2)
// URL: https://codeforces.com/contest/1838/problem/E
// Memory Limit: 256 MB
// Time Limit: 3000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;

const int maxn = 200100;
const ll mod = 1000000007;

inline ll qpow(ll b, ll p) {
	ll res = 1;
	while (p) {
		if (p & 1) {
			res = res * b % mod;
		}
		b = b * b % mod;
		p >>= 1;
	}
	return res;
}

ll n, m, K, f[maxn];

void solve() {
	scanf("%lld%lld%lld", &n, &m, &K);
	for (int i = 0, x; i < n; ++i) {
		scanf("%*d", &x);
	}
	ll ans = qpow(K, m), c = 1;
	for (int i = 0; i < n; ++i) {
		ans = (ans - c * qpow(K - 1, m - i) % mod + mod) % mod;
		c = c * (m - i) % mod * qpow(i + 1, mod - 2) % mod;
	}
	printf("%lld\n", ans);
}

int main() {
	int T = 1;
	scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

posted @ 2023-06-06 17:32  zltzlt  阅读(33)  评论(0)    收藏  举报