洛谷P3600 随机数生成器(期望dp 组合数)
题意
Sol
一条重要的性质:如果某个区间覆盖了另一个区间,那么该区间是没有用的(不会对最大值做出贡献)
首先不难想到枚举最终的答案\(x\)。这时我们需要计算的是最大值恰好为\(x\)的概率。
发现不是很好搞,我们记\(P(x)\)表示最大值\(\leqslant x\)的概率,那么恰好为\(x\)的概率为\(P(x) - P(x - 1)\)
计算概率可以直接用定义:合法的方案/总方案(\(x^n\))
考虑如何计算合法方案:我们直接去枚举在询问区间中有多少个点\(\leqslant x\),设\(g(j)\)表示选出\(j\)个\(\leqslant x\)的点且覆盖了所有询问区间的方案,显然这样可以做到不重不漏。
接下来直接dp计算\(g[j]\),设\(f[i][j]\)表示覆盖了前\(i\)个位置,放了\(j\)个点的方案数,且\(i\)位置必须放的方案数。
\(f[i][j] = \sum_{fr[k] + 1 \leqslant fl[i]} f[k][j - 1]\)
\(fr[i]\)表示覆盖了\(i\)区间的最右区间的编号,\(fl[i]\)表示覆盖了\(i\)的最左区间的编号
转移的时候拿单调栈搞一下
复杂度\(O(n^2 logn)\)
#include<bits/stdc++.h>
#define Pair pair<LL, LL>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
#define LL long long
#define Fin(x) {freopen(#x".in","r",stdin);}
#define Fout(x) {freopen(#x".out","w",stdout);}
using namespace std;
const int MAXN = 2001, mod =666623333, INF = 1e9 + 10;
const double eps = 1e-9;
template <typename A, typename B> inline bool chmin(A &a, B b){if(a > b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline bool chmax(A &a, B b){if(a < b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline LL add(A x, B y) {if(x + y < 0) return x + y + mod; return x + y >= mod ? x + y - mod : x + y;}
template <typename A, typename B> inline void add2(A &x, B y) {if(x + y < 0) x = x + y + mod; else x = (x + y >= mod ? x + y - mod : x + y);}
template <typename A, typename B> inline LL mul(A x, B y) {return 1ll * x * y % mod;}
template <typename A, typename B> inline void mul2(A &x, B y) {x = (1ll * x * y % mod + mod) % mod;}
template <typename A> inline void debug(A a){cout << a << '\n';}
template <typename A> inline LL sqr(A x){return 1ll * x * x;}
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, X, Q, flag[MAXN], fl[MAXN], fr[MAXN], g[MAXN], cnt, tmp[MAXN], f[MAXN][MAXN], que[MAXN], top, sum[MAXN];
int fp(int a, int p) {
int base = 1;
while(p) {
if(p & 1) base = mul(base, a);
a = mul(a, a); p >>= 1;
}
return base;
}
int inv(int x) {
return fp(x, mod - 2);
}
int solve(int x) {//find the probability that max <= x
int now = 0;
for(int i = 1; i <= N; i++) add2(now, mul(g[i], mul(fp(x, i), fp(X - x, N - i))));//choose j point staticfiac
return mul(now, inv(fp(X, N)));
}
Pair q[MAXN];
signed main() {
Fin(a);
N = read(); X = read(); Q = read();
for(int i = 1; i <= Q; i++) q[i].fi = read(), q[i].se = read();
for(int i = 1; i <= Q; i++)
for(int j = 1; j <= Q; j++)
if(!flag[j] && (i != j) && (q[i].fi <= q[j].fi && q[i].se >= q[j].se)) //不加!flag[j]会wa,因为可能左右端点都相同
flag[i] = 1;
for(int i = 1; i <= Q; i++) if(!flag[i]) q[++cnt] = q[i];
Q = cnt;
sort(q + 1, q + Q + 1);
memset(fl, 0x3f, sizeof(fl));
for(int i = 1; i <= Q; i++)
for(int j = 1; j <= N; j++)
if(q[i].fi <= j && q[i].se >= j) chmin(fl[j], i), chmax(fr[j], i);
else if(q[i].se < j) chmax(fr[j], i);
for(int i = 1; i <= N; i++) if(q[fr[i]].se < i) fl[i] = fr[i] + 1;
/*
for(int i = 1; i <= N; i++)
for(int j = 1; j <= min(i, N); j++)
for(int k = 0; k < i; k++)
if(fr[k] + 1 >= fl[i]) add2(f[i][j], f[k][j - 1]);
*/
f[0][0] = 1;
int l = 1, r = 1; que[1] = 0; sum[0] = 1;
for(int i = 1; i <= N; i++) {
while(l <= r && fr[que[l]] + 1 < fl[i]) {
for(int j = 0; j <= N; j++)
add2(sum[j], -f[que[l]][j]);
l++;
}
for(int j = 1; j <= min(i, N); j++) f[i][j] = sum[j - 1];
for(int j = 1; j <= N; j++) add2(sum[j], f[i][j]);
que[++r] = i;
}
for(int i = 1; i <= N; i++)
if(fr[i] == Q)
for(int j = 1; j <= N; j++)
add2(g[j], f[i][j]);
LL ans = 0;
for(int i = 1; i <= N; i++) tmp[i] = solve(i);
for(int i = 1; i <= X; i++) add2(ans, mul(i, add(tmp[i], -tmp[i - 1])));
cout << ans;
return 0;
}
/*
32 4
*/
洛谷P3600 随机数生成器(期望dp 组合数)的更多相关文章
- 洛谷P3600随机数生成器——期望+DP
原题链接 写到一半发现写不下去了... 所以orz xyz32768,您去看这篇题解吧,思路很清晰,我之前写的胡言乱语与之差距不啻天渊 #include <algorithm> #incl ...
- 洛谷 P3600 - 随机数生成器(期望 dp)
题面传送门 我竟然独立搞出了这道黑题!incredible! u1s1 这题是我做题时间跨度最大的题之一-- 首先讲下我四个月前想出来的 \(n^2\log n\) 的做法吧. 记 \(f(a)=\m ...
- luogu P3600 随机数生成器【dp】
把期望改成方案数最后除一下,设h[i]为最大值恰好是i的方案数,那么要求的就是Σh[i]*i 首先包含其他区间的区间是没有意义的,用单调栈去掉 然后恰好不好求,就改成h[i]表示最大值最大是i的方案数 ...
- [洛谷P5147]随机数生成器
题目大意:$$f_n=\begin{cases}\frac{\sum\limits_{i=1}^nf_i}n+1&(n>1)\\0&(n=1)\end{cases}$$求$f_n ...
- 洛谷P3306 随机数生成器
题意:给你一个数列,a1 = x,ai = (A * ai-1 + B) % P,求第一个是t的是哪一项,或者永远不会有t. 解:循环节不会超过P.我们使用BSGS的思想,预处理从t开始跳√P步的,插 ...
- Luogu P3600 随机数生成器
Luogu P3600 随机数生成器 题目描述 sol研发了一个神奇的随机数系统,可以自动按照环境噪音生成真·随机数. 现在sol打算生成\(n\)个\([1,x]\)的整数\(a_1...a_n\) ...
- 洛谷 P5279 - [ZJOI2019]麻将(dp 套 dp)
洛谷题面传送门 一道 dp 套 dp 的 immortal tea 首先考虑如何判断一套牌是否已经胡牌了,考虑 \(dp\).我们考虑将所有牌按权值大小从大到小排成一列,那我们设 \(dp_ ...
- P3600 随机数生成器
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- 洛谷2344 奶牛抗议(DP+BIT+离散化)
洛谷2344 奶牛抗议 本题地址:http://www.luogu.org/problem/show?pid=2344 题目背景 Generic Cow Protests, 2011 Feb 题目描述 ...
随机推荐
- MySQL 基础--时间戳类型
时间戳数据存储 .TimeStamp的取值范围为'1970-01-01 00:00:01' UTC 至'2038-01-19 03:14:07' UTC: .在存储时间戳数据时先将数据转换为UTC时区 ...
- 47_并发编程-线程python实现
一.Threading模块 1.线程的创建 - 方式一 from threading import Thread import time def sayhi(name): time.sleep(2 ...
- 读入挂(IO)
快如闪电,清华杜瑜皓的读入挂,一模一样代码,加了这个之后... 细思极恐,and 整整行!!! namespace IO{ #define BUF_SIZE 100000 #define OUT_SI ...
- Javascript高级编程学习笔记(10)—— 作用域、作用域链
昨天介绍了,JS中函数的作用域 什么词法环境之类的,可能很多小伙伴不太明白. 在今天的内容开始之前,先做个简短的声明: 词法环境这一概念是在ES5中提出的,因为词法环境主要用于保存let.const声 ...
- HTML中META标签的使用
一.META标签简介 <meta> 元素可提供有关页面的元信息,元数据总是以名称/值的形式被成对传递的. <meta> 标签位于文档的头部,不包含任何内容. <meta& ...
- Swift 里的指针
 基础知识 指针的内存状态 typed? initiated? ❌ ❌ ✅ ❌ ✅ ✅ 之前分配的内存可能被释放,使得指针指向了未被分配的内存. 有两种方式可以使得指针指向的内存处于Uninitia ...
- Linux - 查看文件信息的三个命令
ls命令 - list directory contents 显示文件详细信息:ls -l <file name> file命令 - determine file type determi ...
- 200行代码实现简版react🔥
200行代码实现简版react
- 高效的 JavaScript
避免使用 eval 或 Function 构造器 改写 eval 如果你需要函数,使用 function 不要使用 with 不要在要求性能的函数中使用 try-catch-finally 隔离 ev ...
- 【转】浮点数与IEEE 754
http://www.cnblogs.com/kingwolfofsky/archive/2011/07/21/2112299.html 浮点数 1. 什么是浮点数 在计算机系统的发展过程中,曾经 ...