Luogu P3600 随机数生成器

题目描述

sol研发了一个神奇的随机数系统,可以自动按照环境噪音生成真·随机数。

现在sol打算生成\(n\)个\([1,x]\)的整数\(a_1...a_n\),然后进行一些询问。

\(q\)次询问,每次询问i有两个参数\(li\)和\(ri\),sol会计算\(\min_{li \leq j \leq ri} a_j\)(a数组中下标在\(li、ri\)之间的数的最小值)。

最后测试结果会是这些询问得到的结果的最大值。

sol进行了很多次实验,现在他想问问你测试结果的期望大小是多少,对\(666623333\)取模。

输入输出格式

输入格式:

第一行三个数\(n、x、q\)。

下面q行,第i行两个数表示\(li\)和\(ri\)。

输出格式:

一行一个数,表示答案。

输入输出样例

输入样例#1:

2 2 1
1 2

输出样例#1:

499967501

输入样例#2:

6 6 6
1 3
2 4
3 5
4 6
5 6
3 4

输出样例#2:

88571635

根据整数期望公式:

\[\begin{align}
ans&=\sum_{i=1}^xi*p(X=i)\\
&=\sum_{i=1}^xp(X\geq i)\\
&=\sum_{i=1}^x1-p(X<i)
\end{align}
\]

因为是所有的最小值取最大值,所以\(p(X<i)\)比\(p(X\geq i)\)好求一些。

我们考虑对每个\(i\)分别求。

合法情况要求询问的每个区间中至少有一个\(<i\)的数。如果两个区间有包含关系,很明显大的区间没有用。将剩余的区间按左端点排序后,对于坐标上的每个点,包含它的区间的编号一定是连续的。所以我们将问题转换:有很多区间,选择一个区间的概率为\(P\),要选择一些区间将整个坐标轴覆盖,问概率。

很明显这些区间的左右端点都是单调不下降的(去掉无用区间)。设\(f_i\)表示最后一个选择的区间为\(i\),并且将\(r_i\)以及之前的坐标都覆盖了的概率。

\[f_i=\sum_{r_j\geq l_i-1}f_j*P*(1-P)^{i-j-1}
\]

前缀和优化一下单次\(DP\)就可以做到\(O(n)\)了。

代码:

#include<bits/stdc++.h>
#define ll long long
#define N 2005 using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;} const ll mod=666623333;
ll ksm(ll t,ll x) {
ll ans=1;
for(;x;x>>=1,t=t*t%mod)
if(x&1) ans=ans*t%mod;
return ans;
} int n,x,m;
struct interval {
int l,r;
bool operator <(const interval &a)const {
if(l!=a.l) return l<a.l;
return r>a.r;
}
}s[N]; interval st[N];
int top; int L[N],R[N];
ll ans;
ll DP(ll p) {
if(p==1) return 1;
static ll f[N],pw[N],inv[N];
memset(f,0,sizeof(f)); pw[0]=inv[0]=1;
for(int i=1;i<=n;i++) pw[i]=pw[i-1]*(mod+1-p)%mod;
inv[1]=ksm(mod+1-p,mod-2);
for(int i=2;i<=n;i++) inv[i]=inv[i-1]*inv[1]%mod;
f[0]=1;
int lx=0,rx=0;
ll sum=1;
for(int i=1;i<=n;i++) {
while(lx<=i&&R[lx]<L[i]-1) {
sum=(sum-f[lx]*inv[lx]%mod+mod)%mod;
lx++;
}
while(rx+1<i&&R[rx+1]>=L[i]-1) {
sum=(sum+f[rx+1]*inv[rx+1])%mod;
rx++;
}
f[i]=sum*p%mod*pw[i-1]%mod;
}
ll ans=0;
for(int i=1;i<=n;i++) {
if(R[i]==m) (ans+=f[i]*pw[n-i])%=mod;
}
return ans;
} int main() {
n=Get(),x=Get(),m=Get();
for(int i=1;i<=m;i++) s[i].l=Get(),s[i].r=Get();
sort(s+1,s+1+m);
for(int i=1;i<=m;i++) {
while(top>=1&&st[top].r>=s[i].r) top--;
st[++top]=s[i];
} m=top;
for(int i=1;i<=m;i++) s[i]=st[i]; for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) if(s[j].l<=i&&i<=s[j].r) R[i]=j;
for(int j=m;j>=1;j--) if(s[j].l<=i&&i<=s[j].r) L[i]=j;
}
top=0;
for(int i=1;i<=n;i++) {
if(L[i]&&R[i]) L[++top]=L[i],R[top]=R[i];
}
n=top;
ll invx=ksm(x,mod-2);
for(int i=1;i<=x;i++) {
(ans+=mod+1-DP((i-1)*invx%mod))%=mod;
}
cout<<ans;
return 0;
}

Luogu P3600 随机数生成器的更多相关文章

  1. Luogu P3600 随机数生成器(期望+dp)

    题意 有一个长度为 \(n\) 的整数列 \(a_1, a_2, \cdots, a_n\) ,每个元素在 \([1, x]\) 中的整数中均匀随机生成. 有 \(q\) 个询问,第 \(i\) 个询 ...

  2. luogu P3600 随机数生成器【dp】

    把期望改成方案数最后除一下,设h[i]为最大值恰好是i的方案数,那么要求的就是Σh[i]*i 首先包含其他区间的区间是没有意义的,用单调栈去掉 然后恰好不好求,就改成h[i]表示最大值最大是i的方案数 ...

  3. 洛谷P3600 随机数生成器(期望dp 组合数)

    题意 题目链接 Sol 一条重要的性质:如果某个区间覆盖了另一个区间,那么该区间是没有用的(不会对最大值做出贡献) 首先不难想到枚举最终的答案\(x\).这时我们需要计算的是最大值恰好为\(x\)的概 ...

  4. P3600 随机数生成器

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  5. 洛谷P3600随机数生成器——期望+DP

    原题链接 写到一半发现写不下去了... 所以orz xyz32768,您去看这篇题解吧,思路很清晰,我之前写的胡言乱语与之差距不啻天渊 #include <algorithm> #incl ...

  6. 洛谷 P3600 - 随机数生成器(期望 dp)

    题面传送门 我竟然独立搞出了这道黑题!incredible! u1s1 这题是我做题时间跨度最大的题之一-- 首先讲下我四个月前想出来的 \(n^2\log n\) 的做法吧. 记 \(f(a)=\m ...

  7. luogu P2354 [NOI2014]随机数生成器 贪心 卡空间 暴力

    LINK:随机数生成器 观察数据范围还是可以把矩阵给生成出来的. 考虑如何求出答案.题目要求把选出的数字从小到大排序后字典序尽可能的小 实际上这个类似于Mex的问题. 所以要从大到小选数字 考虑选择一 ...

  8. 【原创】开源Math.NET基础数学类库使用(13)C#实现其他随机数生成器

                   本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新  开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...

  9. 【BZOJ-3122】随机数生成器 BSGS

    3122: [Sdoi2013]随机数生成器 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1362  Solved: 531[Submit][Sta ...

随机推荐

  1. jquery仿淘宝购物车页面商品结算(附源码)

    1.效果图如下: 2.源码如下: html部分: <!doctype html> <html lang="en"> <head> <met ...

  2. InnoDB On-Disk Structures(一)-- Tables (转载)

    转载.节选于https://dev.mysql.com/doc/refman/8.0/en/innodb-tables.html 1.InnoDB Architecture The following ...

  3. idea开发时springboot项目时的自动编译和热部署

    前提:最好将idea的启动器设置一下 操作:1.file > Build,Execution,Deployment > Compiler 勾选 Build project automati ...

  4. CG-CTF SQL注入

    SQL注入1 题目 访问题目网址 先查看一下源码 仔细分析一下核心源码 <?php if($_POST[user] && $_POST[pass]) { //判断user和pas ...

  5. 菜鸟刷面试题(三、Redis篇)

    目录: redis是什么?都有哪些使用场景? redis有哪些功能? redis和memecache有什么区别? redis为什么是单线程的? 什么是缓存穿透?怎么解决? redis支持的数据类型有哪 ...

  6. 批量群发,营销必备!Python代码实现自动发送邮件!

    在运维开发中,使用 Python 发送邮件是一个非常常见的应用场景.今天一起来探讨一下,GitHub 的大牛门是如何使用 Python 封装发送邮件代码的. 一般发邮件方法 SMTP是发送邮件的协议, ...

  7. IT兄弟连 HTML5教程 CSS3揭秘 CSS简介

    HTML使用标签将内容放到网页上,也可使用元素和属性来控制简单的文档外观.如果希望更全面地控制Web页面的外观和布局,则需要使用层叠样式表(简写为CSS).CSS规范的工作原理在于允许用户制定一些规则 ...

  8. linux命令--基本权限命令

    一.权限介绍 使用ls命令查看时,发现长格式显示的第一列就是文件的权限 权限位一共有 10 位,这 10 位权限位的含义如下图所示. 第 1 位代表文件类型.Linux 不像 Windows 使用扩展 ...

  9. Spring常用注解式开发

    1.组件注册@Configuration.@Bean给容器中注册组件. 注解,@Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件. 注解,@Bean给Sprin ...

  10. Selenium(十):用By定位元素、鼠标事件、键盘事件

    1. 用By定位元素 除了前面介绍的单位方法,WebDriver还提供了另外一套写法,即统一调用find_element()方法,通过By来声明定位的方法,并且传入对应定位方法的定位参数.具体如下: ...