[Codeforces-div.1 494C] Helping People

试题分析

不难注意到题目所给的性质是一棵树,所以肯定是树形dp。

那么期望没有办法合并,我们还有一种最笨的方法就是求出概率然后直接乘上权值累加。

然后也不难得出朴素的dp:\(f_{i,j}\)表示区间\(i\),最大值为\(mx_i+j\)的概率。

也可以很轻松的写出一个\(O(nm^2)\)的dp,还需优化。

发现转移其中一维是一个前缀和乘积的形式,那么我们改变一下状态:\(f_{i,j}\)表示区间\(i\),最大值\(\leq mx_i+j\)的概率。

带回式子中检查,它是正确的。

于是$$f[x][j]=p_x\prod f[v][mx_x+j-1-mx_v]+(1-p_x)\prod f[v][mx_x+j-mx_v]$$

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm> using namespace std;
#define LL long long inline int read(){
int x=0,f=1; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
}
const int INF = 2147483600;
const int MAXN = 400010;
const double eps = 1e-6; struct data{int l,r; double p;}q[MAXN<<1];
int N,Q; int a[MAXN+1],pre[MAXN+1][31],nod;
vector<int> vec[MAXN<<1]; bool vis[MAXN+1];
double f[5001][11051]; int mx; inline bool cmp(data a,data b){
if(a.l!=b.l) return a.l<b.l;
return a.r>b.r;
}
inline void insert(int rt,int l,int r){
q[++nod].l=l; q[nod].r=r; q[nod].p=0; vec[rt].push_back(nod); return ;
}
inline int build(int rt,int fa,int ql,int qr,int fro){
if(rt) vec[fa].push_back(rt); vis[rt]=true; int x=-1;
for(int l=fro,r;l<=Q;l=r){
if(qr<q[l].r) {x=l; break;}
r=build(l,rt,q[l].l,q[l].r,l+1);
} return (x==-1?Q+1:x);
}
int Log2[MAXN+1];
inline int Qt(int l,int r){
if(l>r) return 0; int x=Log2[r-l+1];
return max(pre[l][x],pre[r-(1<<x)+1][x]);
}
inline int Query(int x){return Qt(q[x].l,q[x].r);}
inline void dfs(int k,int fa){
if(vec[k].empty()) {f[k][0]=1.0-q[k].p;
for(int i=1;i<=Q*2;i++) f[k][i]=1.0; return ;
} int Mx=Query(k);
for(int i=0;i<vec[k].size();i++) dfs(vec[k][i],k);
for(int i=0;i<=Q;i++) {
double t1,t2; t1=t2=1.0;
for(int j=0;j<vec[k].size();j++){
t1=t1*f[vec[k][j]][Mx+i-1-Query(vec[k][j])];
t2=t2*f[vec[k][j]][Mx+i-Query(vec[k][j])];
} f[k][i]=(i?q[k].p:0)*t1+(1.0-q[k].p)*t2;
} for(int i=Q+1;i<=Q*2;i++) f[k][i]=f[k][i-1];
return ;
}
inline double calc(){
double ret=mx;
for(int i=1;i<=Q;i++) ret+=(f[0][i]-f[0][i-1])*i; return ret;
} int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
N=read(),Q=read(); for(int i=1;i<=N;i++) pre[i][0]=a[i]=read(),mx=max(mx,a[i]);
if(mx>Q) for(int i=1;i<=N;i++) pre[i][0]=a[i]=max(0,a[i]+Q-mx); for(int i=2;i<=N;i++) Log2[i]=Log2[i>>1]+1;
for(int j=1;j<=21;j++) for(int i=1;i+(1<<j)-1<=N;i++) pre[i][j]=max(pre[i][j-1],pre[i+(1<<(j-1))][j-1]);
for(int i=1;i<=Q;i++) q[i].l=read(),q[i].r=read(),scanf("%lf",&q[i].p); sort(q+1,q+Q+1,cmp); nod=Q;
q[0].l=1,q[0].r=N;q[0].p=0; build(0,-1,1,N,1); dfs(0,-1); printf("%.10lf\n",calc());
return 0;
}

[Codeforces-div.1 494C] Helping People的更多相关文章

  1. Codeforces Round #533 (Div. 2) E - Helping Hiasat 最大团

    E - Helping Hiasat 裸的最大团,写了一种 2 ^ (m / 2)  * (m / 2)的复杂度的壮压, 应该还有更好的方法. #include<bits/stdc++.h> ...

  2. 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 ...

  3. Codeforces Round #533 (Div. 2) E. Helping Hiasat(最大独立集)

    题目链接:https://codeforces.com/contest/1105/problem/E 题意:有 n 个事件,op = 1 表示我可以修改昵称,op = 2 表示一个名为 s_i 的朋友 ...

  4. Codeforces 494C - Helping People

    题意 有一个长度为 \(n\) 的数列 \(a\),有 \(m\) 个 操作,每个操作是给 \(a[l_i,r_i]\) 中的数都加一,一个操作有 \(p_i\) 的概率执行(否则不执行).一个性质是 ...

  5. Codeforces Round #802 (Div. 2)C. Helping the Nature(差分)

    题目链接 题目大意: 给你一个有n个元素的数组a,你可以通过一下三种操作使数组的每一个值都为0: 选择一个下标i,然后让a[1],a[2]....a[ i ] 都减一; 选择一个下标i,然后让a[i] ...

  6. codeforces div.1 A

    A. Efim and Strange Grade time limit per test 1 second memory limit per test 256 megabytes input sta ...

  7. Codeforces div.2 B. The Child and Set

    题目例如以下: B. The Child and Set time limit per test 1 second memory limit per test 256 megabytes input ...

  8. codeforces泛做..

    前面说点什么.. 为了完成日常积累,傻逼呵呵的我决定来一发codeforces 挑水题 泛做.. 嗯对,就是泛做.. 主要就是把codeforces Div.1的ABCD都尝试一下吧0.0.. 挖坑0 ...

  9. [CF787D]遗产(Legacy)-线段树-优化Dijkstra(内含数据生成器)

    Problem 遗产 题目大意 给出一个带权有向图,有三种操作: 1.u->v添加一条权值为w的边 2.区间[l,r]->v添加权值为w的边 3.v->区间[l,r]添加权值为w的边 ...

随机推荐

  1. Spring中获取request的几种方法,及其线程安全性分析(山东数漫江湖)

    前言 本文将介绍在Spring MVC开发的web系统中,获取request对象的几种方法,并讨论其线程安全性. 原创不易,如果觉得文章对你有帮助,欢迎点赞.评论.文章有疏漏之处,欢迎批评指正. 欢迎 ...

  2. 父元素与子元素之间的margin-top问题(css hack)

    hack: 父元素的盒子包含一个子元素盒子,给子元素盒子一个垂直外边距margin-top,父元素盒子也会往下走margin-top的值,而子元素和父元素的边距则没有发生变化. hytml代码: &l ...

  3. Python面向对象学习2(面向对象的语法和特性,待更新)

    上一个内容我们介绍了面向对象和面向对象场景现在我们来学习下语法和特性 1,面向对象基本语法: # -*- coding:utf-8 -*- # Author: Colin Yao class Dog( ...

  4. Bagging和Boosting 概念及区别(转)

    Bagging和Boosting都是将已有的分类或回归算法通过一定方式组合起来,形成一个性能更加强大的分类器,更准确的说这是一种分类算法的组装方法.即将弱分类器组装成强分类器的方法. 首先介绍Boot ...

  5. 如何修改或美化linux终端

    先丢一张效果图: 如何让您的 LD 的终端更具个性呢?首先,我们需要了解下面几点知识.A:配置文件 个人配置文件:~/.bashrc全局设定文件:/etc/bash.bashrc(修改需要管理员权限) ...

  6. ubuntu下定时弹窗记录工作日志

    背景 记录工作日志,是一个很好的习惯,但不容易坚持,本来打算每天记录,但经常拖延,拖着拖着,有一些事情就忘记了. 等到写周报或月报的时候,才会开始翻邮件,聊天记录,各个仓库的提交log等,回忆都干了些 ...

  7. HDU 5129 Yong Zheng's Death

    题目链接:HDU-5129 题目大意为给一堆字符串,问由任意两个字符串的前缀子串(注意断句)能组成多少种不同的字符串. 思路是先用总方案数减去重复的方案数. 考虑对于一个字符串S,如图,假设S1,S2 ...

  8. HDU 6146 Pokémon GO DP,计数

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6146 题意:~ 解法:原题..http://blog.csdn.net/y990041769/arti ...

  9. Java将CST的时间字符串转换成需要的日期格式字符串

    已知得到的Date类型的变量meettingdate 的值为Sun Dec 16 10:56:34 CST :现在要将它改为yyyy-MM-dd类型或yyyy年MM月dd日: 变为yyyy年MM月dd ...

  10. 多路复用I/O模型poll() 模型 代码实现

    多路复用I/O模型poll() 模型 代码实现 poll()机制和select()机制是相似的,都是对多个描述符进行轮询的方式. 不同的是poll()没有描述符数目的限制. 是通过struct pol ...