Codeforces 494C - Helping People
题意
有一个长度为 \(n\) 的数列 \(a\),有 \(m\) 个 操作,每个操作是给 \(a[l_i,r_i]\) 中的数都加一,一个操作有 \(p_i\) 的概率执行(否则不执行)。一个性质是任意两个区间不相交或完全包含(可重叠)。问执行完所有操作后 \(a\) 中最大值的期望。
\(n\le 10^5,m\le 5000,a\le 10^9\) 。
分析
想象一下多个不相交或完全包含的区间,他们的结构其实是一棵树。外层为父亲,内层为儿子。
要计算的是最大值的期望,而这个最大值是由多个操作得到的,所以无法分别计算期望再合并。解决这个问题的方法是先算出概率,再得到期望。
到最后,一个区间 \([l,r]\) 的最大值只可能是 \([mx,mx+q]\) 中的数(\(mx\) 为原序列中这个区间的最大值)。那么那么我们可以用这个东西来 dp。
设 \(f[x][j]\) 表示 \(x\) 点子树中的操作结束后,\(x\) 点表示的这个区间的最大值小于等于 \(mx_x+j\) 的概率。这样设计是因为若是等于的话,计算的时候转移还是要求前缀和,相当于是小于等于了。若 \(x\) 这个操作不执行,那么从子树 \(v\) 转移,子树 \(v\) 需要让其最后的区间最大值小于等于 \(mx_x+j\) ;若执行,那么子树的需要让其区间最大值小于等于 \(mx_i+j-1\) 。因此有转移
\]
代码
#include<bits/stdc++.h>
using namespace std;
const int maxq=5e3+5;
const int maxm=1e4+5;
const int maxn=1e5+1;
int n,a[maxn],m,M,mx;
inline void Max(int &x,int y) {x=max(x,y);}
struct Q {
int l,r,mx;
double p;
inline bool operator < (const Q &b) const {return l!=b.l?l<b.l:r>b.r;}
} q[maxq];
namespace rmq {
const int maxj=17;
int f[maxn][maxj],bin[maxn];
void build() {
for (int i=2;i<=n;++i) bin[i]=bin[i>>1]+1;
for (int i=1;i<=n;++i) f[i][0]=a[i];
for (int j=1;j<maxj;++j) for (int i=1;i<=n;++i) {
int x=i+(1<<(j-1));
f[i][j]=f[i][j-1];
if (x<=n && f[x][j-1]>f[i][j]) f[i][j]=f[x][j-1];
}
}
inline int query(int l,int r) {
int x=bin[r-l+1];
return max(f[l][x],f[r-(1<<x)+1][x]);
}
}
namespace tree {
vector<int> g[maxq];
double f[maxq][maxm];
inline void add(int x,int y) {g[x].push_back(y);}
void build() {
sort(q+1,q+m+1);
static int sta[maxq],top;
q[sta[top=0]=0]=(Q){1,n,min(mx,m),0};
for (int i=1;i<=m;++i) {
Q &p=q[i];
for (;top>0 && p.l>q[sta[top]].r;--top) add(sta[top-1],sta[top]);
sta[++top]=i;
}
for (;top;--top) add(sta[top-1],sta[top]);
}
void dfs(int x) {
if (g[x].empty()) {
f[x][0]=1-q[x].p;
for (int i=1;i<=M;++i) f[x][i]=1;
return;
}
for (const int &v:g[x]) dfs(v);
for (int j=0;j<=m;++j) {
double fir=j?q[x].p:0,sec=1-q[x].p;
for (const int &v:g[x]) {
int the=q[x].mx-q[v].mx+j;
fir*=f[v][the-1];
sec*=f[v][the];
}
f[x][j]=fir+sec;
}
for (int j=m+1;j<=M;++j) f[x][j]=f[x][j-1];
}
double calc() {
double ret=mx;
for (int i=1;i<=m;++i) ret+=(f[0][i]-f[0][i-1])*i;
return ret;
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
#endif
scanf("%d%d",&n,&m),M=m<<1;
for (int i=1;i<=n;++i) {
scanf("%d",a+i);
Max(mx,a[i]);
}
if (mx>m) for (int i=1;i<=n;++i) a[i]=max(0,a[i]+m-mx);
rmq::build();
for (int i=1;i<=m;++i) {
scanf("%d%d%lf",&q[i].l,&q[i].r,&q[i].p);
q[i].mx=rmq::query(q[i].l,q[i].r);
}
tree::build();
tree::dfs(0);
double ans=tree::calc();
printf("%.10lf\n",ans);
return 0;
}
Codeforces 494C - Helping People的更多相关文章
- [Codeforces-div.1 494C] Helping People
[Codeforces-div.1 494C] Helping People 试题分析 不难注意到题目所给的性质是一棵树,所以肯定是树形dp. 那么期望没有办法合并,我们还有一种最笨的方法就是求出概率 ...
- CodeForces 1105E Helping Hiasat 最大独立集
Helping Hiasat 题解: 如果我们把连续的2出现的人都相互连边的话, 题目就是问最大独立集的答案是多少. 求最大独立集可以将图变成反图, 然后求最大团. 代码: #include<b ...
- 【Codeforces 1105E】Helping Hiasat
Codeforces 1105 E 题意:给你m个事件,每个事件可能是以下两种之一: \(1\),代表此时可以更改用户名 \(2\) \(s\),代表\(s\)来查看是否用户名与其名字相符 一共有\( ...
- Codeforces Round #533 (Div. 2) E - Helping Hiasat 最大团
E - Helping Hiasat 裸的最大团,写了一种 2 ^ (m / 2) * (m / 2)的复杂度的壮压, 应该还有更好的方法. #include<bits/stdc++.h> ...
- Codeforces #282 div 1 C Helping People 题解
CF 282 C Helping People 题解 [原题] time limit per test 2 seconds memory limit per test 512 megabytes in ...
- Codeforces Round #533 (Div. 2) E. Helping Hiasat(最大独立集)
题目链接:https://codeforces.com/contest/1105/problem/E 题意:有 n 个事件,op = 1 表示我可以修改昵称,op = 2 表示一个名为 s_i 的朋友 ...
- Solution -「CF 494C」Helping People
\(\mathcal{Description}\) Link. 给定序列 \(\{a_n\}\) 和 \(m\) 个操作,第 \(i\) 个操作有 \(p_i\) 的概率将 \([l_i,r_ ...
- Codeforces Round #802 (Div. 2)C. Helping the Nature(差分)
题目链接 题目大意: 给你一个有n个元素的数组a,你可以通过一下三种操作使数组的每一个值都为0: 选择一个下标i,然后让a[1],a[2]....a[ i ] 都减一; 选择一个下标i,然后让a[i] ...
- Codeforces Round #439 (Div. 2) Problem E (Codeforces 869E) - 暴力 - 随机化 - 二维树状数组 - 差分
Adieu l'ami. Koyomi is helping Oshino, an acquaintance of his, to take care of an open space around ...
随机推荐
- Python2.7-anydbm
anydbm模块,把各种数据库模块(dbhash (requires bsddb), gdbm, or dbm)的接口进行了统一.打开后返回的对象操作和字典类似 模块方法: anydbm.open(f ...
- 搭建windows远程节点_jmeter自动化测试环境(接口测试)
WINDOWS10系统下 环境 172.16.0.115虚拟机windows系统作为远程节点. jenkins安装在172.16.0.119:8088虚拟机中. 一.安装配置Java环境 wind ...
- 【转】为什么volatile不能保证原子性而Atomic可以?
直接上好文链接!!! 为什么volatile不能保证原子性而Atomic可以?
- DQN(Deep Reiforcement Learning) 发展历程(五)
目录 值函数的近似 DQN Nature DQN DDQN Prioritized Replay DQN Dueling DQN 参考 DQN发展历程(一) DQN发展历程(二) DQN发展历程(三) ...
- 20155220 Exp2 后门原理与实践
20155220 Exp2 后门原理与实践 1.Windows获得Linux Shell 在windows下,打开CMD,使用ipconfig指令查看本机IP 然后使用ncat.exe程序,ncat. ...
- [2016北京集训测试赛17]crash的游戏-[组合数+斯特林数+拉格朗日插值]
Description Solution 核心思想是把组合数当成一个奇怪的多项式,然后拉格朗日插值..:哦对了,还要用到第二类斯特林数(就是把若干个球放到若干个盒子)的一个公式: $x^{n}=\su ...
- 阿里云OSS不同账号之间的迁移
目录 一.需求说明 二.Ossimport概述 三.配置运行环境 1.配置jdk环境 2.部署方式 3.下载并部署ossimport 四.修改单机Job的配置文件local_job.cfg 五.执行迁 ...
- python删除文件与目录的方法
python内置方法删除目录(空目录与非空目录)及文件 1.os.remove(file_path):删除文件 #PPTV是文件夹,xen.txt是文件 >>> os.remove( ...
- mybatis源码-解析配置文件(二)之解析的流程
目录 1. 简介 2. 配置文件解析流程分析 2.1 调用 2.2 解析的目的 2.3 XML 解析流程 2.3.1 build(parser) 2.3.2 new XMLConfigBuilder( ...
- yocto-sumo源码解析(五): bitbake/lib/bb/main.py
续前面分析,就该对bitbake_main()这个函数进行分析了,这个函数位于bitbake/lib/bb/main.py. 1. 检测主机操作系统是否为linux并且/dev/shm是否存在,pyt ...