CF494C Helping People

Posted zh-comld

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF494C Helping People相关的知识,希望对你有一定的参考价值。

http://codeforces.com/problemset/problem/494/C

题解

注意到区间之间没有交叉,所以只有包含的关系,我们可以把它整成一棵树。

然后设一下\(dp[i][j]\)表示以\(i\)为根的子树,最大值不超过区间最大值+\(j\)的概率。

转移:
\[ dp[u][j]=p*\prod dp[v][mx[u]-mx[v]-1+j]+(1-p)*\prod dp[v][mx[u]-mx[v]+j] \]

代码

#include<bits/stdc++.h>
#define N 100002
#define M 5002
using namespace std;
typedef long long ll;
int n,nw[N],top,mx[M],q,st[N];
vector<int>vec[N];
double f[M][M],ans,g[M][M];
int size[M];
inline ll rd()
  ll x=0;char c=getchar();bool f=0;
  while(!isdigit(c))if(c=='-')f=1;c=getchar();
  while(isdigit(c))x=(x<<1)+(x<<3)+(c^48);c=getchar();
  return f?-x:x;

struct node
  int l,r;double p;
  inline bool operator <(const node &b)const
    if(l!=b.l)return l<b.l;
    else return r>b.r;   
  
a[M];
void dfs(int u)
    int l=a[u].l;
    size[u]=u!=0;
    for(vector<int>::iterator it=vec[u].begin();it!=vec[u].end();++it)
        int v=*it;
        dfs(v);
        for(int i=l;i<a[v].l;++i)mx[u]=max(mx[u],nw[i]);
        mx[u]=max(mx[u],mx[v]);
        l=a[v].r+1;
    
    for(int i=l;i<=a[u].r;++i)mx[u]=max(mx[u],nw[i]);
    int now=mx[u];
    for(vector<int>::iterator it=vec[u].begin();it!=vec[u].end();++it)
        int v=*it;
        mx[u]=max(mx[u],mx[v]);
    
    for(int i=0;i<=q;++i)
        f[u][i]=(1-a[u].p);
        g[u][i]=a[u].p;
     
    if(now==mx[u])g[u][0]=0;
    for(vector<int>::iterator it=vec[u].begin();it!=vec[u].end();++it)
        int v=*it;
        size[u]+=size[v];
        for(int j=0;j<=size[u];++j)
            if(mx[u]-mx[v]-1+j<=size[u]&&mx[u]-mx[v]-1+j>=0)g[u][j]*=f[v][mx[u]-mx[v]-1+j];
            if(mx[u]-mx[v]+j<=size[u])f[u][j]*=f[v][mx[u]-mx[v]+j];
        
    
    for(int i=0;i<=q;++i)f[u][i]+=g[u][i];

int main()
  n=rd();q=rd();
  for(int i=1;i<=n;++i)nw[i]=rd();
  for(int i=1;i<=q;++i)
    a[i].l=rd();a[i].r=rd();scanf("%lf",&a[i].p);
  
  sort(a+1,a+q+1);
  for(int i=1;i<=q;++i)
    while(top&&a[st[top]].r<a[i].l)top--;
    vec[st[top]].push_back(i);
    st[++top]=i;
  
  a[0].l=1;a[0].r=n;
  dfs(0);
  for(int i=0;i<=q;++i)
    double x=i?f[0][i]-f[0][i-1]:f[0][0];
    ans+=x*(mx[0]+i);
  
  printf("%.9lf",ans);
  return 0;

以上是关于CF494C Helping People的主要内容,如果未能解决你的问题,请参考以下文章

[Codeforces-div.1 494C] Helping People

Codeforces #282 div 1 C Helping People 题解

CF1105E Helping Hiasat

CF1105E Helping Hiasat

$CF1105E Helping Hiasat$ 最大团

E - Helping the HR Gym - 102040E