Codeforces #282 div 1 C Helping People 题解
CF 282 C
Helping People 题解
【原题】
2 seconds
512 megabytes
standard input
standard output
Malek is a rich man. He also is very generous. That's why he decided to split his money between poor people. A charity institute knows npoor people numbered
from 1 to n. The institute gave Malek q recommendations.
A recommendation is a segment of people like [l, r]which means the institute recommended that Malek gives one dollar to every person whose number
is in this segment.
However this charity has very odd rules about the recommendations. Because of those rules the recommendations are given in such a way that for every two recommendation [a, b] and [c, d] one
of the following conditions holds:
- The two segments are completely disjoint. More formally either a ≤ b < c ≤ d or c ≤ d < a ≤ b
- One of the two segments are inside another. More formally either a ≤ c ≤ d ≤ b or c ≤ a ≤ b ≤ d.
The goodness of a charity is the value of maximum money a person has after Malek finishes giving his money. The institute knows for each recommendation what is the probability that Malek will
accept it. They want to know the expected value of goodness of this charity. So they asked you for help.
You have been given the list of recommendations and for each recommendation the probability of it being accepted by Malek. You have also been given how much money each person initially has. You must find the expected value of goodness.
In the first line two space-separated integers n, q (1 ≤ n ≤ 105, 1 ≤ q ≤ 5000)
are given.
In the second line n space-separated integers a1, a2, ..., an (0 ≤ ai ≤ 109)
are given meaning that person number i initially has ai dollars.
Each of the next q lines contains three space-separated numbers li, ri, pi (1 ≤ li ≤ ri ≤ n, 0 ≤ p ≤ 1)
where li and ri are
two integers describing the segment of recommendation and pi is
a real number given with exactly three digits after decimal point which is equal to probability of Malek accepting this recommendation.
Note that a segment may appear several times in recommendations.
Output the sought value. Your answer will be considered correct if its absolute or relative error is less than 10 - 6.
5 2
1 7 2 4 3
1 3 0.500
2 2 0.500
8.000000000
5 2
281 280 279 278 282
1 4 1.000
1 4 0.000
282.000000000
3 5
1 2 3
1 3 0.500
2 2 0.250
1 2 0.800
1 1 0.120
2 2 0.900
4.465000000
【废话】好久没写博客了。(我不会告诉你我是离线写的)于是来水经验来了。
【来源简述】CF 282 C
【原题简述】有N(10^5)个人,每一个人有初始的钱。
再给出M(5000)个操作L,R,P。
每次表示L~R这些人有几率P(0<=P<=1)给他们每人一元。
求最后全部人钱数最大值的期望。
【算法简述】首先把这些操作建立出树结构(能够借鉴线段树)。
节点i表示范围Li~Ri,它的父亲一定包括它,它也包括它的全部子树。为了方便,建立一个L=1,R=N,P=0的无效节点作为根。
观察到M的范围小。我们用f[i][j]表示在节点i表示的范围内,加的钱数<=j的期望(注意原先的钱数能够用RMQ计算出)。至于为什么是<=,由于后面要用到前缀和——反正f算的时候再前缀和一下。那么到节点i,我们开一数组tmp[j]表示全部子树中影的最多(注意还是前缀和性质)加了j元的期望。
那么tmp[j]= ∏f[son][mx[i]+j-mx[son]];
mx[o]是原先区间o的最大钱数。
(这里就用到了f的前缀和性质了)
注意到求完后做一步tmp[j]-=tmp[j-1],取消前缀和性质。
然后我们的任务是求出i的全部f值。
那么ans[i][j]=ans[i][j-1]+tmp[j-1]*p[i]+tmp[j]*(1-p[i]);
ans[i][j-1]:前缀和
tmp[j-1]*p[i]:由子树中得最大加j-1,且当前也加
tmp[j]*(1-p[i]):由子树中得最大加j,且当前不加
求完了全部的f[i][j]后,我们对于新加的点K,最后的ans满足
ANS=ans[m][0]*mx[m]+Σ (ans[m][i]-ans[m][i-1])*(mx[m]+i);
【*精华所得】类似于分治的树形算法。
【代码】
#include<cstdio>
#include<algorithm>
#include<cmath>
#define N 100005
#define M 5005
using namespace std;
struct arr{int l,r;double p;}a[M];
int f[N][18],mx[N],used[N],n,i,j,T,m,k;
double ans[M][M],tmp[M],ANS;
inline int ask(int x,int y)
{
int len=(int)log2(y-x+1);
return max(f[x][len],f[y-(1<<len)+1][len]);
}
inline int cmp(const arr &a,const arr &b){return a.r-a.l<b.r-b.l;}
int main()
{
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++) scanf("%d",&f[i][0]);
for (j=1;j<=17;j++)
for (i=1;i<=n;i++)
T=i+(1<<(j-1)),f[i][j]=max(f[i][j-1],(T<=n)? f[T][j-1]:0);
for (i=1;i<=m;i++)
scanf("%d%d%lf",&a[i].l,&a[i].r,&a[i].p);
a[++m]=(arr){1,n,0};
sort(a+1,a+m+1,cmp);
for (i=1;i<=m;i++)
{
mx[i]=ask(a[i].l,a[i].r);
for (k=0;k<=m;k++) tmp[k]=1.0;
for (j=1;j<i;j++)
if (a[j].l>=a[i].l&&a[j].r<=a[i].r&&!used[j])
{
used[j]=1;
for (k=0;k<=m;k++)
if (mx[i]+k-mx[j]<=m) tmp[k]*=ans[j][mx[i]+k-mx[j]];
}
for (k=m;k;k--)
tmp[k]-=tmp[k-1];
ans[i][0]=(1-a[i].p)*tmp[0];
for (k=1;k<=m;k++)
ans[i][k]=ans[i][k-1]+tmp[k-1]*a[i].p+tmp[k]*(1-a[i].p);
//ans[i][k-1]:加上k-1的期望(ans[i]实质是前缀和性质)
//tmp[k-1]*p[i]:由子树中得最大加k-1,且当前也加
//tmp[k]*(1-p[i]): 由子树中得最大加k,且当前不加
}
ANS=ans[m][0]*mx[m];
for (i=1;i<=m;i++)
ANS+=(ans[m][i]-ans[m][i-1])*(mx[m]+i);
printf("%.10lf",ANS);
}
Codeforces #282 div 1 C Helping People 题解的更多相关文章
- 【codeforces #282(div 1)】AB题解
A. Treasure time limit per test 2 seconds memory limit per test 256 megabytes input standard input o ...
- Codeforces Round #609 (Div. 2)前五题题解
Codeforces Round #609 (Div. 2)前五题题解 补题补题…… C题写挂了好几个次,最后一题看了好久题解才懂……我太迟钝了…… 然后因为longlong调了半个小时…… A.Eq ...
- Codeforces #344 Div.2
Codeforces #344 Div.2 Interview 题目描述:求两个序列的子序列或操作的和的最大值 solution 签到题 时间复杂度:\(O(n^2)\) Print Check 题目 ...
- Lyft Level 5 Challenge 2018 - Final Round (Open Div. 2) (前三题题解)
这场比赛好毒瘤哇,看第四题好像是中国人出的,怕不是dllxl出的. 第四道什么鬼,互动题不说,花了四十五分钟看懂题目,都想砸电脑了.然后发现不会,互动题从来没做过. 不过这次新号上蓝名了(我才不告诉你 ...
- Codeforces #345 Div.1
Codeforces #345 Div.1 打CF有助于提高做题的正确率. Watchmen 题目描述:求欧拉距离等于曼哈顿距离的点对个数. solution 签到题,其实就是求有多少对点在同一行或同 ...
- Codeforces Beta Round #27 (Codeforces format, Div. 2)
Codeforces Beta Round #27 (Codeforces format, Div. 2) http://codeforces.com/contest/27 A #include< ...
- Codeforces#441 Div.2 四小题
Codeforces#441 Div.2 四小题 链接 A. Trip For Meal 小熊维尼喜欢吃蜂蜜.他每天要在朋友家享用N次蜂蜜 , 朋友A到B家的距离是 a ,A到C家的距离是b ,B到C ...
- codeforces #592(Div.2)
codeforces #592(Div.2) A Pens and Pencils Tomorrow is a difficult day for Polycarp: he has to attend ...
- codeforces #578(Div.2)
codeforces #578(Div.2) A. Hotelier Amugae has a hotel consisting of 1010 rooms. The rooms are number ...
随机推荐
- spring in action 学习笔记十四:用纯注解的方式实现spring mvc
在讲用纯注解的方式实现springmvc之前先介绍一个类:AbstractAnnotationDispatcherServletInitializer.这个类的作用是:任何一个类继承AbstractA ...
- js函数调用与声明 (for时注意)
可以的: test(); // 直接function 方式声明的函数可以直接调用,后声明 function test(){} aa(); //error var 方式声明的函数需先声明后调用v ...
- nutch2.3.1源码分析——InjectorJob
InjectorJob实现的功能是:从种子站点文件当中读取站点信息并且将这些站点的个数.url(url以 域名:协议/端口号/路径名 设为形式存储在数据库当中,为了提高读写速度)回写到Context类 ...
- YUY格式
YUV格式有两大类:planar和packed. 对于planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V. 对于packed的YUV格式,每个像素点的Y ...
- 汕头市队赛 SRM10 T1模拟只会猜题意
模拟只会猜题意 SRM 10 描述 有一本n个单词的词典,求按下列方法能造出的不相同的词汇数目. 1.词典中的单词是一个词. 2.能分为两部分的,其中前一部分是一个词典词或者其非空前缀,后一部分是一 ...
- weblogic12c配置免密码启动
在运行startWeblogic.sh时需要输入有效的账号密码才能启动weblogic,为简化操作,可以配置boot.properties来免输账号密码,配置方法如下:1.查看在./domains/x ...
- [LeetCode] Sort List 排序 sort
Sort a linked list in O(n log n) time using constant space complexity. Hide Tags Linked List Sort ...
- F28379D烧写双核程序(在线&离线)
烧写双核程序前需知在分别对F28379D的CPU1和CPU2两个核进行烧写程序时,需要在CCS中建立两个工程,独立编写两个核的程序.如controlSUITE中提供的双核程序例程: 1. 在线1.1 ...
- 华为上机测试题(MP3光标移动-java)
PS:此题满分,可参考 描述: MP3 Player因为屏幕较小,显示歌曲列表的时候每屏只能显示几首歌曲,用户要通过上下键才能浏览所有的歌曲.为了简化处理,假设每屏只能显示4首歌曲,光标初始的位置为第 ...
- python 的requests如何使用代理
headers.py import random first_num = random.randint(55, 62) third_num = random.randint(0, 3200) four ...