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. C语言入门-枚举

    常量符号化 用符号而不是具体的数字来表示程序中的数字 一. 枚举 用枚举而不是定义独立的const int变量 枚举是一种用户定义的数据类型,它用关键字enum如以下语句来声明 enum 枚举类型名字 ...

  2. android 启动流程 相关2 init进程 属性服务

    Init属性服务 系统属性服务 属性梳理 来源和读取时机 来源:内核参数 ro.kernel.*   代表有qemu内核参数才会设置(在虚拟机中) ro.boot.*     1.内核设备树相关的设备 ...

  3. 谷歌chrome浏览器被毒霸上网导航www.uu114.cn劫持 chrome://version命令行被篡改

    问题描述 win10系统更新, 谷歌chrome浏览器打开后自动跳转到被劫持的网站.我的被hao123劫持, 瞬间对hao123的好感度下降浏览器输入chrome://version 可以看到“命令行 ...

  4. 【洛谷5492】[PKUWC2018] 随机算法(状压DP)

    点此看题面 大致题意: 用随机算法求一张图的最大独立集:每次随机一个排列,从前到后枚举排列中的点,如果当前点加入点集中依然是独立集,就将当前点加入点集中,最终得到的点集就是最大独立集.求这个随机算法的 ...

  5. ubuntu 安装谷歌浏览器

    如何在ubuntu 中安装谷歌浏览器, 对于一个刚刚接触ubuntu的人来说,希望安装软件更加的简单,明了.最好能够像在windows下面安装软件一样. 先来介绍一下如何快速的安装谷歌浏览器,以下的方 ...

  6. Navicat Premium连接mongodb基本使用和介绍

    Navicat premium是一款数据库管理工具,是一个可多重连线资料库的管理工具, 它可以让你以单一程式同时连线到 MySQL.SQLite.Oracle 及 PostgreSQL,mongodb ...

  7. pandas.apply()函数

    1.介绍 apply函数是pandas里面所有函数中自由度最高的函数.该函数如下: DataFrame.apply(func, axis=0, broadcast=False, raw=False, ...

  8. SpringBoot2.0 基础案例(17):自定义启动页,项目打包和指定运行环境

    本文源码 GitHub地址:知了一笑 https://github.com/cicadasmile/spring-boot-base 一.打包简介 springboot的打包方式有很多种.可以打war ...

  9. SharePoint PowerShell 创建网站栏

    前言 最近,有这么个需求,需要使用PowerShell为网站集创建网站栏,好吧,直接看代码吧. Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorA ...

  10. k8s kubernetes 核心笔记 镜像仓库 项目k8s改造(含最新k8s v1.16.2版本)

    k8s kubernetes 核心笔记 镜像仓库 项目k8s改造 2019/10/24 Chenxin 一 基本资料 一 参考: https://kubernetes.io/ 官网 https://k ...