luoguP3600 随机数生成器 期望概率DP + DP优化

这篇题解更像对他人题解的吐槽和补充?
考虑答案
$E[X] = \sum\limits_{i = 1}^{x} i P(X = i)$
$P(X = i)$不好求................(其实完全可以求的......而且求法和下面的方法蜜汁相似......)
那么,我们考虑整数概率公式(既然$P(X = i)$能求,那这公式到底有什么用?)
$E[X] = \sum\limits_{i = 1}^{x} P(x \geq i)$
当然,你也可以选择求$E[X] = \sum\limits_{i = 1}^{x} i * (P(x \geq i) - P(x \geq i + 1))$
或者求$E[X] = \sum\limits_{i = 1}^{x} i * (P(x \leq i + 1) - P(x \leq i))$
不过方法没什么本质的区别..........
那么,考虑求枚举$x$后求$P(x \geq i)$,由于题目是最大值,这是“或”概率,不好求
因此考虑“非与非”,即求反面$1 - P(x \leq i - 1)$
相信你能发现,被包含的区间的答案是无所谓的...
因此,将区间去包含就成了随着左端点递增,右端点递增的局面
接着,考虑一个点能让哪些区间得出正确的结果然后转移
不妨设一个点能影响的区间为$[L[i], R[i]]$,记为$S[i]$
令$f[i]$表示让第$i$个小于$x$,并且$1 ... R[i]$的所有询问都合法的概率
为了方便书写,令随机出小于等于$v$的数的概率为$p$,那么$p = \frac{v}{x}$
那么,我们枚举跟$i$的区间有交的$j$,然后让$[i + 1, j - 1]$强行大于$v$转移
(注意,需要认为存在一段$[0, 0]$的区间,并且$0$已经选择了小于等于$v$的数来辅助转移,因此开始要特判...)
$f[i] = (p * \sum\limits_{S[i] \cap S[j] \neq \varnothing} f[j] * (1 - p)^{i - j - 1})$
用$two - pointer$和前缀和可以优化到$O(n)$
(只要去掉开头的$p$就是求$P(x = i)$了,但是这么做在有点没被区间覆盖时不能采用下面的算法)
(需要单独把没有被区间覆盖的点拿出来,不让他们参与转移...毕竟$p + 1 - p = 1$,但是$1 - p \neq 1$,这么写略麻烦)
那如果有些点完全没被区间覆盖怎么办呢?
不妨设$[l_1, r_1], [l_2, r_2]$编号为$i, j$,且有$l_1 \leq r_1 < l_2 \leq r_2$
那么对于$[r_1 + 1, l_2 - 1]$中的点,令其$S = [j, i]$(没写错)
这时,$i$能顺利地转移到$S$一次,同时把$S$和右边的第一块没有被两个区间交的部分绑在了一起转移....
(这可以保证增加区间$[0, 0]$和区间$[n + 1, n+1]$的正确性)
(然而出题人并没有谈,所以数据保证所有的点都被区间覆盖?)
最后求$P(x < i)$的时候,相当于还单独存在一段$[n + 1, n + 1]$的区间,并且$n + 1$已经选择了小于$i$的数...
可以选择加上这段区间或者最后特判下....
复杂度$O(nx)$
注:$luogu$最近是不是慢了....
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; extern inline char gc() {
static char RR[], *S = RR + , *T = RR + ;
if(S == T) fread(RR, , , stdin), S = RR;
return *S ++;
}
inline int read() {
int p = , w = ; char c = gc();
while(c > '' || c < '') { if(c == '-') w = -; c = gc(); }
while(c >= '' && c <= '') p = p * + c - '', c = gc();
return p * w;
} #define ri register int
#define sid 2005
const int mod = ; int n, x, q, ans;
int ps[sid], snp;
int L[sid], R[sid], f[sid], inv[sid], fac[sid];
struct seg {
int l, r;
friend bool operator < (seg a, seg b)
{ return a.l < b.l || (a.l == b.l && a.r > b.r); }
} s[sid]; int fp(int a, int k) {
int ret = ;
for( ; k; k >>= , a = 1ll * a * a % mod)
if(k & ) ret = 1ll * ret * a % mod;
return ret;
} int main() {
n = read(); x = read(); q = read();
for(ri i = ; i <= q; i ++) {
int l = read(), r = read();
s[i].l = l; s[i]. r = r;
} sort(s + , s + q + );
for(ri i = ; i <= q; i ++) {
while(s[i].r <= s[ps[snp]].r) snp --;
ps[++ snp] = i;
}
q = snp; for(ri i = ; i <= q; i ++) s[i] = s[ps[i]]; int fr = , to = ;
for(ri i = ; i <= n; i ++) {
while(to < q && s[to + ].l <= i) to ++;
while(fr <= to && s[fr].r < i) fr ++;
L[i] = fr; R[i] = to;
} for(ri v = ; v <= x; v ++) {
int p = 1ll * (v - ) * fp(x, mod - ) % mod, bp = ( - p + mod) % mod;
int pc = fp(bp, mod - ), sum = ;
inv[] = fac[] = f[] = ;
for(ri i = ; i <= n; i ++) {
inv[i] = 1ll * inv[i - ] * pc % mod;
fac[i] = 1ll * fac[i - ] * bp % mod;
}
for(ri i = , j = ; i <= n; i ++) {
while(j < i && R[j] < L[i] - ) ((sum -= 1ll * f[j] * inv[j] % mod) += mod) %= mod, j ++;
f[i] = 1ll * sum * fac[i - ] % mod * p % mod;
(sum += 1ll * f[i] * inv[i] % mod) %= mod;
}
int anp = ;
for(ri i = ; i <= n; i ++)
if(R[i] == q) (anp += 1ll * f[i] * fac[n - i] % mod) %= mod;
(ans += ( - anp + mod) % mod) %= mod;
}
printf("%d\n", ans);
return ;
}
luoguP3600 随机数生成器 期望概率DP + DP优化的更多相关文章
- 洛谷P3600 随机数生成器(期望dp 组合数)
题意 题目链接 Sol 一条重要的性质:如果某个区间覆盖了另一个区间,那么该区间是没有用的(不会对最大值做出贡献) 首先不难想到枚举最终的答案\(x\).这时我们需要计算的是最大值恰好为\(x\)的概 ...
- 洛谷P3600随机数生成器——期望+DP
原题链接 写到一半发现写不下去了... 所以orz xyz32768,您去看这篇题解吧,思路很清晰,我之前写的胡言乱语与之差距不啻天渊 #include <algorithm> #incl ...
- luogu P4284 [SHOI2014]概率充电器 期望 概率 树形dp
LINK:概率充电器 大概是一个比较水的题目 不过有一些坑点. 根据期望的线性性 可以直接计算每个元件的期望 累和即为答案. 考虑统计每一个元件的概率的话 那么对其有贡献就是儿子 父亲 以及自己. 自 ...
- 【bzoj5197】[CERC2017]Gambling Guide 期望dp+堆优化Dijkstra
题目描述 给定一张n个点,m条双向边的无向图. 你要从1号点走到n号点.当你位于x点时,你需要花1元钱,等概率随机地买到与x相邻的一个点的票,只有通过票才能走到其它点. 每当完成一次交易时,你可以选择 ...
- BZOJ1415: [Noi2005]聪聪和可可 最短路 期望概率dp
首先这道题让我回忆了一下最短路算法,所以我在此做一个总结: 带权: Floyed:O(n3) SPFA:O(n+m),这是平均复杂度实际上为O(玄学) Dijkstra:O(n+2m),堆优化以后 因 ...
- 洛谷 P4284 [SHOI2014]概率充电器 概率与期望+换根DP
洛谷 P4284 [SHOI2014]概率充电器 概率与期望+换根DP 题目描述 著名的电子产品品牌\(SHOI\) 刚刚发布了引领世界潮流的下一代电子产品-- 概率充电器: "采用全新纳米 ...
- HDU 3853 期望概率DP
期望概率DP简单题 从[1,1]点走到[r,c]点,每走一步的代价为2 给出每一个点走相邻位置的概率,共3中方向,不动: [x,y]->[x][y]=p[x][y][0] , 右移:[x][y ...
- 【BZOJ 3652】大新闻 数位dp+期望概率dp
并不难,只是和期望概率dp结合了一下.稍作推断就可以发现加密与不加密是两个互相独立的问题,这个时候我们分开算就好了.对于加密,我们按位统计和就好了;对于不加密,我们先假设所有数都找到了他能找到的最好的 ...
- 【BZOJ 3811】玛里苟斯 大力观察+期望概率dp+线性基
大力观察:I.从输出精准位数的约束来观察,一定会有猫腻,然后仔细想一想,就会发现输出的时候小数点后面不是.5就是没有 II.从最后答案小于2^63可以看出当k大于等于3的时候就可以直接搜索了 期望概率 ...
随机推荐
- Mock InjectMocks ( @Mock 和 @InjectMocks )区别
之前一直对这两个注解的区别不是很明白. 搜到过一篇博客园的文章举例说明了代码行为的区别.后来在stackoverflow上看到一个问答简单明了的解释了这两个注解在定义上的区别: 在此翻译记录一下: / ...
- LintCode 394: First Will Win
LintCode 394: First Will Win 题目描述 有n个硬币排成一条线.两个参赛者轮流从右边依次拿走1或2个硬币,直到没有硬币为止.拿到最后一枚硬币的人获胜. 请判定 第一个玩家 是 ...
- 2017 ACM暑期多校联合训练 - Team 3 1008 HDU 6063 RXD and math (莫比乌斯函数)
题目链接 Problem Description RXD is a good mathematician. One day he wants to calculate: ∑i=1nkμ2(i)×⌊nk ...
- [网站安全] [实战分享]WEB漏洞挖掘的一些经验分享
WEB漏洞有很多种,比如SQL注入,比如XSS,比如文件包含,比如越权访问查看,比如目录遍历等等等等,漏洞带来的危害有很多,信息泄露,文件上传到GETSHELL,一直到内网渗透,这里我想分享的最主要的 ...
- 在Perl中使用Getopt::Long模块来接收用户命令行参数
我们在linux常常用到一个程序需要加入参数,现在了解一下perl中的有关控制参数的函数.getopt.在linux有的参数有二种形式.一种是–help,另一种是-h.也就是-和–的分别.–表示完整参 ...
- python 之ConfigParser模块学习
1.1 读取配置文件 -read(filename) 直接读取ini文件内容 -sections() 得到所有的section,并以列表的形式返回 -options(section) 得到该secti ...
- loadrunner 测试问题汇总
1.关于Error -27791: Error -27790:Error -27740: 错误如下: Action.c(198): Error -27791: Server ...
- Python学习笔记——数据结构和算法(二)
1.字典中一个键映射多个值 可以使用collections中的defaultdict来实现,defalultdict接受list或者set为参数 from collections import def ...
- Geoserver WFS跨域设置
测试版本为geoserver2.11.0. 两种方法都可以实现跨域设置: 第一种: 下载跨域jar包jetty-servlets.jar(下载geoserver使用的对应jetty版本——可以查看&l ...
- 对cgic的理解——name选项
#include <stdio.h>#include <stdlib.h>#include <string.h>#include "cgic.h" ...