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的时候就可以直接搜索了 期望概率 ...
随机推荐
- 【洛谷】3375 KMP字符串匹配
[算法]KMP [题解][算法]字符串 #include<cstdio> #include<algorithm> #include<cstring> using n ...
- 【BZOJ】3527: [Zjoi2014]力 FFT
[参考]「ZJOI2014」力 - FFT by menci [算法]FFT处理卷积 [题解]将式子代入后,化为Ej=Aj-Bj. Aj=Σqi*[1/(i-j)^2],i=1~j-1. 令f(i)= ...
- jQuery domready
在jQuery里面,我们可以看到两种写法: $(function(){ //todo }) $(document).ready(function(){ //todo }) 这两个方法的效果都是一样的, ...
- AJAX的前世今生与未来
一.通过三个问答来认识一下Ajax 什么是Ajax? Ajax是Asynchronous Javascript And XML的缩写,它是一种技术. Ajax有什么用? 这一技术能够向服务器请求额外的 ...
- Network POJ - 3694 (LCA+tarjan+桥)
题目链接:https://vjudge.net/problem/POJ-3694 具体思路:首先可以通过缩点的方式将整个图变成一个树,并且树的每条边是桥,但是我们可以利用dfn数组将整个图变成树,这样 ...
- flask基础之安装和使用入门(一)
前言 Flask框架作为一个python极简化的web框架,它不像Django那样的重型,非常适合快速开发一些小型的应用.本人用flask开发了几个项目之后,慢慢研究flask底层的一些原理,开始一步 ...
- SQLite3数据库的操作
数据库的操作 我们在这个项目中使用的是SQLITE3数据库软件. 通过使用SQLITE3进行创建数据库,创建表,插入记录,查询记录,更新记录,关闭数据库等操作来实现将相应的数据存入数据库中. 打开数据 ...
- Ubuntu命令设置ip网关dns
本文系转载,介绍Ubuntu如何设置IP和网络来连接网络 如果是在虚拟机中使用Ubuntu,那么设置之前请先参照我的上一遍文章虚拟机Net方式设置连接外网中的网络设置部分,先设置好主机的网络,然后配置 ...
- javaScript如何跳出多重循环break、continue
先来说说break和continue之间的区别 for(var i=0;i<10;i++){ if(i>5){ break; }}console.log(i); ---6 •当i ...
- Kaggle:Titanic: Machine Learning from Disaster
一直想着抓取股票的变化,偶然的机会在看股票数据抓取的博客看到了kaggle,然后看了看里面的题,感觉挺新颖的,就试了试. 题目如图:给了一个train.csv,现在预测test.csv里面的Passa ...