Luogu P3600 随机数生成器(期望+dp)
题意
有一个长度为 \(n\) 的整数列 \(a_1, a_2, \cdots, a_n\) ,每个元素在 \([1, x]\) 中的整数中均匀随机生成。
- 有 \(q\) 个询问,第 \(i\) 个询问的结果是下标在 \([l_i , r_i ]\) 的元素的最小值。
- 求这 \(q\) 个询问结果的最大值的期望,\(\bmod 666623333\) 。
数据范围
\(1 \le n, q, x \le 2000\) 。
题解
参考了 fjzzq2002 的题解。
有个很有用的结论。
对于非负实数变量 \(X\) 我们有:
\[\mathbb E(X) = \int_{0}^{\infty} P(X \ge x) \mathrm dx
\]对于 \(X\) 是离散的非负整数变量的情况,我们有:
\[\mathbb E(X) = \sum_{x = 1}^{\infty} P(X \ge x)
\]如何理解呢?我们可以考虑期望的定义式 \(\mathbb E(X) = \sum_{x} P(X = x) x\) 其实是一个数面积的过程,也就是积分。
然后等式两边的其实就是数面积的两种过程,一个是竖着数,另外一个是横着数。推广一下其实如果是求 \(\mathbb E(f(X))\) 我们考虑求导后积分也就是:
\[\mathbb E(f(x)) = \int_{0}^{\infty} f'(x) P(X \ge x) \mathrm dx
\]
我们套用这个后就有
\]
这样就好做多了,考虑枚举 \(i\) ,然后算 \(P(ans \le i)\) 也就是,每个区间的 \(\min\) 都 \(\le i\) 的概率,假设这个 \(i = t\) 。
我们发现如果一个区间包含另外一个区间的话,那么它的最小值一定不会比小区间大,所以一定不会贡献到答案,那么我们可以去掉大区间。转化后,所有区间就是互不包含的了。
考虑记 \(f_i\) 为右端点不超过 \(i\) 的区间询问结果都 \(\le t\) 的概率。
如果不存在一个 \(r = i\) ,那么就是 \(f_i = f_{i - 1}\) 。
否则记右端点为 \(i\) 的区间左端点为 \(j\) ,枚举区间内最后一个 \(\le t\) 的数的位置 \(l\) ,那么我们有
\]
然后发现是 \(\mathcal O(xn^2)\) 的,发现它能跑过QAQ
显然我们可以使它更加正确,推导一下式子就有(注意有 \(t < x\) )
\]
然后我们就可以用前缀和优化到 \(\mathcal O(xn)\) 。
其实还可以继续优化。。
观察转移方程发现答案其实是一个关于 \(\displaystyle \frac tx\) 的 \(\mathcal O(n)\) 次多项式,也就是关于 \(i\) 的 \(\mathcal O(n)\) 次多项式。
所以它的前缀和仍然是一个 \(\mathcal O(n)\) 次多项式,我们算出前 \(\mathcal O(n)\) 项和前缀和,插值出 \(x\) 处的前缀和即可。复杂度就优化成 \(\mathcal O(n^2)\) 啦。
代码
#include <bits/stdc++.h>
#define For(i, l, r) for (register int i = (l), i##end = (int)(r); i <= i##end; ++i)
#define Fordown(i, r, l) for (register int i = (r), i##end = (int)(l); i >= i##end; --i)
#define Rep(i, r) for (register int i = (0), i##end = (int)(r); i < i##end; ++i)
#define Set(a, v) memset(a, v, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define debug(x) cout << #x << ": " << (x) << endl
#define l first
#define r second
using namespace std;
typedef pair<int, int> PII;
template<typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, T b) { return b > a ? a = b, 1 : 0; }
inline int read() {
int x(0), sgn(1); char ch(getchar());
for (; !isdigit(ch); ch = getchar()) if (ch == '-') sgn = -1;
for (; isdigit(ch); ch = getchar()) x = (x * 10) + (ch ^ 48);
return x * sgn;
}
void File() {
#ifdef zjp_shadow
freopen ("P3600.in", "r", stdin);
freopen ("P3600.out", "w", stdout);
#endif
}
const int N = 2e3 + 1e2, Mod = 666623333;
inline int fpm(int x, int power) {
int res = 1;
for (; power; power >>= 1, x = 1ll * x * x % Mod)
if (power & 1) res = 1ll * res * x % Mod;
return res;
}
int n, x, q, len, f[N]; PII S[N];
int V[N], powb[N], invpowb[N], sum[N];
int main () {
File();
n = read(); x = read(); q = read();
For (i, 1, q)
S[i].l = read(), S[i].r = read();
sort(S + 1, S + q + 1);
For (i, 1, q) {
bool flag = true;
For (j, i + 1, q)
if (S[i].l <= S[j].l && S[j].r <= S[i].r) flag = false;
if (flag)
V[S[i].r] = S[i].l;
}
int ans = 0, invx = fpm(x, Mod - 2);
Rep (v, x) {
f[0] = powb[0] = invpowb[0] = 1;
int coef = 1ll * v * invx % Mod;
powb[1] = (Mod + 1 - coef) % Mod;
invpowb[1] = fpm(powb[1], Mod - 2);
For (i, 2, n) {
powb[i] = 1ll * powb[i - 1] * powb[1] % Mod;
invpowb[i] = 1ll * invpowb[i - 1] * invpowb[1] % Mod;
}
For (i, 1, n) {
sum[i] = (sum[i - 1] + 1ll * f[i - 1] * invpowb[i]) % Mod;
if (!V[i]) f[i] = f[i - 1];
else f[i] = 1ll * (Mod + sum[i] - sum[V[i] - 1]) * coef % Mod * powb[i] % Mod;
}
(ans += Mod + 1 - f[n]) %= Mod;
}
printf ("%d\n", ans);
return 0;
}
Luogu P3600 随机数生成器(期望+dp)的更多相关文章
- 洛谷P3600 随机数生成器(期望dp 组合数)
题意 题目链接 Sol 一条重要的性质:如果某个区间覆盖了另一个区间,那么该区间是没有用的(不会对最大值做出贡献) 首先不难想到枚举最终的答案\(x\).这时我们需要计算的是最大值恰好为\(x\)的概 ...
- luogu P3600 随机数生成器【dp】
把期望改成方案数最后除一下,设h[i]为最大值恰好是i的方案数,那么要求的就是Σh[i]*i 首先包含其他区间的区间是没有意义的,用单调栈去掉 然后恰好不好求,就改成h[i]表示最大值最大是i的方案数 ...
- 洛谷P3600随机数生成器——期望+DP
原题链接 写到一半发现写不下去了... 所以orz xyz32768,您去看这篇题解吧,思路很清晰,我之前写的胡言乱语与之差距不啻天渊 #include <algorithm> #incl ...
- Luogu P3600 随机数生成器
Luogu P3600 随机数生成器 题目描述 sol研发了一个神奇的随机数系统,可以自动按照环境噪音生成真·随机数. 现在sol打算生成\(n\)个\([1,x]\)的整数\(a_1...a_n\) ...
- Luogu P3251 [JLOI2012]时间流逝 期望dp
题面 题面 题解 期望\(dp\)好题! 今年\(ZJOI\)有讲过这题... 首先因为\(T\)只有\(50\),大力\(dfs\)后发现,可能的状态数最多只有\(20w\)左右,所以我们就可以大力 ...
- 洛谷 P3600 - 随机数生成器(期望 dp)
题面传送门 我竟然独立搞出了这道黑题!incredible! u1s1 这题是我做题时间跨度最大的题之一-- 首先讲下我四个月前想出来的 \(n^2\log n\) 的做法吧. 记 \(f(a)=\m ...
- luoguP3600 随机数生成器 期望概率DP + DP优化
这篇题解更像对他人题解的吐槽和补充? 考虑答案 $E[X] = \sum\limits_{i = 1}^{x} i P(X = i)$ $P(X = i)$不好求................(其实 ...
- P3600 随机数生成器
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- Luogu P1850 换教室(期望dp)
P1850 换教室 题意 题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有\(2n\)节课程安排在\(n\)个时间段上.在第\(i(1\l ...
随机推荐
- Dynamics 365-Full Text Index on Stopwords
之前写了一篇关于Online Relevance Search的博文,然后又看到罗勇大神关于Full Text Index的博文:Dynamics CRM中一个查找字段引发的[血案],于是准备写点关于 ...
- 在android studio中配置运行时签名
做项目的时候,有时需要用到第三方接口,而基本第三方接口都是要求我们要先进行签名.结果每次调试都得手动进行签名一次,实在麻烦.所以android studio提供了一种在运行的时候自动进行签名的方法,在 ...
- (办公)TOKEN
token就是HTTP认证,输入正确的token,在放在Authorization header中发送给服务器,认证成功.,就可以正确的拿到接口数据. 举个例子: 第一步: 客户端发送http re ...
- MongoDB 提升性能的18原则(开发设计阶段)
MongoDB 是高性能数据,但是在使用的过程中,大家偶尔还会碰到一些性能问题.MongoDB和其它关系型数据库相比,例如 SQL Server .MySQL .Oracle 相比来说,相对较新,很多 ...
- python3 OrderedDict类(有序字典)
创建有序字典 import collections dic = collections.OrderedDict() dic['k1'] = 'v1' dic['k2'] = 'v2' dic['k3' ...
- 一道C++、MFC上机面试题
题目:写一个基于MFC对话框的程序,界面输入整型a和b,点击计算,开启线程计算a+b,并把结果返回给对话框.(1)不能用结构体和类(2)用到自定义消息(3)鼠标移到[计算]按钮上变为收尸图标.参考界面 ...
- Docker: 构建Nginx,PHP,Tomcat基础镜像
Usage: docker build [OPTIONS] PATH | URL | - [flags] Options: -t, --tag list # 镜像名称 -f, --file strin ...
- China Tightens Recycling Import Rules
China Tightens Recycling Import Rules We have all seen the pictures of cities in China with air poll ...
- 英语口语练习系列-C03-常用问句
连接到英语口语系列总分类 连接到上一章抱怨 枫桥夜泊 How are you doing?你好吗? 美国人见面时候最常用的打招呼方式: "Hey! How are you doing?&qu ...
- Ubuntu18.04 安装jdk1.8
1.oracle官网下载压缩包,点击链接. 2.解压 1 tar -zxvf jdk-8u171-linux-x64.tar.gz 3.移动到制定目录 ##将文件从下载目录 挪到/usr/local下 ...