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. Eclipse中如何添加相对路径的外部jar包

    在eclipse中进行java编程的时候,常常需要引用外部jar包.而采用相对路径引用jar包可以大大方便java工程的拷贝,这样使得java工程从一个路径转移到另一个路径时不用大费周章的修改外包ja ...

  2. ios 免费抓包工具Stream

    ios 免费抓包工具Streamhttps://www.52pojie.cn/thread-1002406-1-1.html

  3. JavaScript中使用正则表达式

    JavaScript中正则表达式的使用 创建正则对象 RegExp 对象是带有预定义属性和方法的正则表达式对象. 方式一: var reg = new RegExp("\d", ' ...

  4. button的onclick事件给函数传递参数

    ul+='<button onclick="pay(\''+regiId+'\')" >按钮</button>' //此为原生JS页面拼接//此方式的关键就 ...

  5. Swoole Redis 连接池的实现

    概述 这是关于 Swoole 入门学习的第九篇文章:Swoole Redis 连接池的实现. 第八篇:Swoole MySQL 连接池的实现 第七篇:Swoole RPC 的实现 第六篇:Swoole ...

  6. linux命令--网络命令

    一.网络命令 1.配置ip 1.1 配置 IP 地址 IP 地址是计算机在互联网中唯一的地址编码.每台计算机如果需要接入网络和其他计算机进行数 据通信,就必须配置唯一的公网 IP 地址. 配置 IP ...

  7. GO-结构体(类似python中的类)

    一.结构体有名属性 package main import "fmt" func main(){ type Sb struct { name string //属性名,数据类型 a ...

  8. ArcGIS Server10.4 service发布步骤

    准备内容 安装环境:win10*64位专业版 安装文件:ArcGIS_Server_Ent_Windows_1041_150998.iso 破解文件:Lic10.4.1.ecp #安装Server前, ...

  9. ThinkPHP6框架的下载与安装

    thinkphp6发布也有一段时间了,相对来说比较稳定,是时候学习一下thinkphp6框架,提前学习,到正式发布的时候,可以直接拿来做正式的项目,先人一步.thinkPHP6.0在5.1的基础上对底 ...

  10. 通过官网模板轻松实现Grafana的可视化界面配置(以MySQL监控项为例)

    我们知道可视化是监控的一个重要环节,所以往往我们这个环节花费大量的时间和精力.可是如果可以借鉴前辈的经验和成果,可以事半功倍.Grafana 有着非常漂亮的图表和布局展示,功能齐全的度量仪表盘和图形编 ...