CodeForces 1838E Count Supersequences
结论:\(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;
}

浙公网安备 33010602011771号