P3600 随机数生成器
第一眼想到了minmax容斥可还行。。。
注意到 max 套个 min 很不好,我们考虑把 max 容斥掉,考虑:
注意到一个集合最小值的期望只和它的大小有关,对于一个大小为 的集合,最小值期望显然是 ,我们只需要对于每个长度,统计出并出它的方案的系数和。考虑 dp。
首先,如果一个区间包含令一个区间,那它显然没用,我们直接删去它。这样我们所有区间都没有包含关系。然后按右端点排序,设 表示考虑前 个区间,强制选第 个,区间并长度为 ,选了偶数/奇数个区间的方案数,那么枚举上一个选的区间是什么, 的背包是显然的。
考虑优化,注意到本质不同的转移只有两种,设当前区间为 ,上一个区间为 ,如果 ,显然会从 转移过来,这是个定值,由于 递增,满足条件的上一个区间是一段前缀,可以记录前缀和转移。如果 ,则区间有交。由于区间互不包含,新增的段一定是最右边的一段,会从 转移过来。我们记 ,显然会从 的 转移过来,这也可以做前缀和转移。
#include <bits/stdc++.h>
using namespace std;
const int N = 2005, B = 2100, mod = 666623333;
inline int read() {
register int s = 0, f = 1; register char ch = getchar();
while (!isdigit(ch)) f = (ch == '-' ? -1 : 1), ch = getchar();
while (isdigit(ch)) s = (s * 10) + (ch & 15), ch = getchar();
return s * f;
}
inline int power(int a, int b) {
int t = 1, y = a, k = b;
while (k) {
if (k & 1) t = 1ll * t * y % mod;
y = 1ll * y * y % mod; k >>= 1;
} return t;
}
struct node {
int l, r;
} p[N];
inline bool cmp(node a, node b) {
return a.r < b.r;
}
bool vis[N];
int f[2005][2][2005], g[2005][2][2005], n, m, q, pw[N], t[N], res[N];
unordered_map<int, int> h[2005][2];
int main() {
n = read(); m = read(); q = read();
for (int i = 1; i <= q; ++i) {
p[i].l = read(); p[i].r = read();
} int top = 0;
for (int i = 1; i <= q; ++i) {
for (int j = 1; j <= q; ++j) {
if (i == j) continue;
if (p[i].l <= p[j].l && p[j].r <= p[i].r) {
if (vis[j] && p[i].l == p[j].l && p[i].r == p[j].r) continue;
vis[i] = 1; break;
}
}
}
for (int i = 1; i <= q; ++i)
if (!vis[i]) p[++top] = p[i];
int cnt = 0;
sort(p + 1, p + top + 1, cmp);
f[0][0][0] = 1; g[0][0][0] = 1; h[0][0][0] = 1;
for (int i = 1; i <= top; ++i) {
for (int j = 0; j <= 1; ++j) {
int L = 0;
for (int k = 1; k < i; ++k)
if (p[k].r < p[i].l) L = k;
else break;
memcpy(g[i][j], g[i - 1][j], sizeof g[i][j]);
h[i][j] = h[i - 1][j];
for (int k = p[i].r - p[i].l + 1; k <= p[i].r; ++k) {
f[i][j][k] += g[L][j ^ 1][k - (p[i].r - p[i].l + 1)];
f[i][j][k] += h[i - 1][j ^ 1][k - p[i].r] - h[L][j ^ 1][k - p[i].r];
if (f[i][j][k] >= mod) f[i][j][k] -= mod;
if (f[i][j][k] < 0) f[i][j][k] += mod;
g[i][j][k] += f[i][j][k];
if (g[i][j][k] >= mod) g[i][j][k] -= mod;
h[i][j][k - p[i].r] += f[i][j][k];
if (h[i][j][k - p[i].r] >= mod) h[i][j][k - p[i].r] -= mod;
if (j) res[k] += f[i][j][k];
else res[k] -= f[i][j][k];
if (res[k] >= mod) res[k] -= mod;
if (res[k] < 0) res[k] += mod;
}
}
} int ans = 0;
for (int i = 1; i <= m; ++i) pw[i] = 1;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
pw[j] = 1ll * j * pw[j] % mod;
t[i] += pw[j]; if (t[i] >= mod) t[i] -= mod;
} t[i] = 1ll * t[i] * power(power(m, mod - 2), i) % mod;
ans += 1ll * t[i] * res[i] % mod;
if (ans >= mod) ans -= mod;
} printf("%d\n", ans); return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App