首页 > 其他分享 >CF494C Helping People 题解

CF494C Helping People 题解

时间:2024-03-23 22:35:15浏览次数:15  
标签:5010 CF494C limits 题解 long times Helping max define

题目传送门

前置知识

概率 DP | 树形 DP |RMQ

解法

观察到区间只有相离或包含关系,类似线段树的管辖区间,考虑将其构成树形关系。为方便代码书写,将原来的森林构成一棵树,即增加一个区间 \(l_{q+1}=1,r_{q+1}=n,p_{q+1}=0\)。

由于对于一个区间 \([l,r]\) 的最大值在经历任意次操作后,一定有 \(\max\limits_{k=l}^{r} \{ a_{k} \} \le \max\limits_{k=l}^{r} \{ a_{k}' \} \le \max\limits_{k=l}^{r} \{ a_{k} \}+q\),故可以据此优化空间。设 \(f_{x,i}\) 表示第 \(x\) 个节点对应的区间的最大值 \(\le \max\limits_{k=x_{l}}^{x_{r}} \{ a_{k} \}+i\) 的概率,状态转移方程为 \(\begin{cases} f_{x,i}=(1-p_{x}) \times \prod\limits_{y \in Son(x)}f_{y,\min(q+1,\max\limits_{k=x_{l}}^{x_{r}} \{ a_{k} \}+i-\max\limits_{k=y_{l}}^{y_{r}} \{ a_{k} \})} & i=0 \\ f_{x,i}=p_{x} \times \prod\limits_{y \in Son(x)}f_{y,\min(q+1,\max\limits_{k=x_{l}}^{x_{r}} \{ a_{k} \}+i-\max\limits_{k=y_{l}}^{y_{r}} \{ a_{k} \}-1)}+(1-p_{x}) \times \prod\limits_{y \in Son(x)}f_{y,\min(q+1,\max\limits_{k=x_{l}}^{x_{r}} \{ a_{k} \}+i-\max\limits_{k=y_{l}}^{y_{r}} \{ a_{k} \})} & i \ne 0 \end{cases}\)。

假设区间按照左端点升序,右端点降序的方式排序。最终,有 \(f_{1,0} \times \max\limits_{k=1}^{n} \{ a_{k} \}+\sum\limits_{i=1}^{q+1}(f_{1,i}-f_{1,i-1}) \times (i+ \max\limits_{k=1}^{n} \{ a_{k} \})\) 即为所求。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define ull unsigned long long
#define sort stable_sort 
#define endl '\n'
struct edge
{
    int nxt,to;
}e[5010];
struct node
{
    int l,r,maxx;
    double p;
}b[5010];
int head[5010],a[100010],fmaxx[100010][20],cnt=0;
double f[5010][5010];
bool cmp(node a,node b)
{
    return (a.l==b.l)?(a.r>b.r):(a.l<b.l);
}
void init(int n)
{
    for(int j=1;j<=log2(n);j++)
    {
        for(int i=1;i<=n-(1<<j)+1;i++)
        {
            fmaxx[i][j]=max(fmaxx[i][j-1],fmaxx[i+(1<<(j-1))][j-1]);
        }
    }
}
int query(int l,int r)
{
    int t=log2(r-l+1);
    return max(fmaxx[l][t],fmaxx[r-(1<<t)+1][t]);
}
void add(int u,int v)
{
    cnt++;
    e[cnt].nxt=head[u];
    e[cnt].to=v;
    head[u]=cnt;
}
void dfs(int x,int q)
{
    double sum1,sum2=1;
    for(int i=head[x];i!=0;i=e[i].nxt)
    {
        dfs(e[i].to,q);
        sum2*=f[e[i].to][min(q,b[x].maxx+0-b[e[i].to].maxx)];
    }
    f[x][0]=(1-b[x].p)*sum2;
    for(int i=1;i<=q;i++)
    {
        sum1=sum2=1;
        for(int j=head[x];j!=0;j=e[j].nxt)
        {
            sum1*=f[e[j].to][min(q,b[x].maxx+i-b[e[j].to].maxx-1)];
            sum2*=f[e[j].to][min(q,b[x].maxx+i-b[e[j].to].maxx)];
        }
        f[x][i]=b[x].p*sum1+(1-b[x].p)*sum2;
    }
}
int main()
{
    int n,q,i,j;
    double ans=0;
    cin>>n>>q;
    for(i=1;i<=n;i++)
    {
        cin>>a[i];
        fmaxx[i][0]=a[i];
    }
    init(n);
    for(i=1;i<=q;i++)
    {
        cin>>b[i].l>>b[i].r>>b[i].p;
        b[i].maxx=query(b[i].l,b[i].r);
    }
    q++;
    b[q].l=1;
    b[q].r=n;
    b[q].p=0;
    b[q].maxx=query(1,n);
    sort(b+1,b+1+q,cmp);
    for(i=1;i<=q;i++)
    {   
        for(j=i-1;j>=1;j--)
        {
            if(b[j].l<=b[i].l&&b[i].r<=b[j].r)
            {
                add(j,i);
                break;
            }
        }
    }
    dfs(1,q);
    for(i=0;i<=q;i++)
    {
        ans+=(f[1][i]-(i==0?0:f[1][i-1]))*(i+b[1].maxx);
    }
    printf("%.9lf\n",ans);
    return 0;
}	     	 			 	 		   		     	

标签:5010,CF494C,limits,题解,long,times,Helping,max,define
From: https://www.cnblogs.com/The-Shadow-Dragon/p/18091815

相关文章

  • CF922E Birds 题解
    题目传送门前置知识背包DP解法观察到\(w\)极大,若使用正常的背包空间会爆炸。依据AT_dp_eKnapsack2的经验,考虑将背包“反”着用。设\(f_{i,j}\)表示到第\(i\)棵树时一共召唤了\(j\)只小鸟时剩余的最大魔力值,状态转移方程为\(f_{i,j}=\min(\max\limits_{k=0}^{\m......
  • [暴力题解系列] 2023年蓝桥杯-冶炼金属
    世界上存在很难的题,但不存在暴力偷不到分的题​ 这题的暴力思路比你想的更简单,我直接枚举v的数值不就行了?#include<iostream>#include<algorithm>usingnamespacestd;inta[10010],b[10010];intmain(){intn;scanf("%d",&n);for(inti=1;i<=n;i++)......
  • P10268 符卡对决 题解
    题目链接:符卡对决视频讲解待上传经典的题目,对于这个\([l,r]\)询问,我们先关注期望怎么算。考虑方案总数和有效的和,方案总数显然有\(\dfrac{n\times(n-1)}{2}\),现在还需要关注有效和,我们关注对于若干个有效的关系用一个比较形象的数据结构表示-----并查集,那么两个卡牌之间有......
  • CF1711B Party 题解
    CF1711BParty原题题意给定$n$个点带点权的无向图,点权$a_i$保证无重边自环,点权非负),要求删去一些点和它相连的边,使得剩下这个图的边数为偶数且删去点的点权之和最小。问删去点的点权之和最小是多少?分类讨论我们分类讨论一下。$m$为偶数,则不需要删边或点,直接输出$0$即......
  • 洛谷P3498 [POI2010] KOR-Beads 题解
    P3498[POI2010]KOR-Beads对于数列${A_i}$,求$k$使数列被分为$\lfloor\frac{n}{k}\rfloor$个部分后不同子数列种类最多(子串翻转前后为一类子串)很容易想到:枚举$k\\in\[1,n]$,记录每个$k$下不同种类数,然后取最优即可,那么问题来了:如何计算种类数?暴戾算法:一种纯......
  • 跳马【华为OD机试JAVA&Python&C++&JS题解】
    一.题目马是象棋(包括中国象棋和国际象棋)中的棋子,走法是每步直一格再斜一格,即先横着或直着走一格,然后再斜着走一个对角线,可进可退,可越过河界,俗称“马走‘日’字。给顶m行n列的棋盘(网格图),棋盘上只有有棋子象棋中的棋子“马”,并且每个棋子有等级之分,等级为k的马可以跳1~k......
  • CF710D Two Arithmetic Progressions 题解
    CF710DTwoArithmeticProgressions根号分治薄纱数论看日报学习的根号分治:暴力美学——浅谈根号分治-paulzrm的博客。开始想学ODT的映射思想的推广-金珂拉的博客,结果先学了ODT,又学了根号分治,才搞懂前置知识。什么是根号分治根号分治,是暴力美学的集大成体现。与......
  • [暴力题解系列]2023年蓝桥杯-子串简写
    ​ 大伙都说暴力是最低级的算法,啊那确实。但是好的暴力才是真正牛逼的骗分。咱就是说,暴力如何骗分呢?就是基于最暴力的算法一步步优化到能得更多分的暴力。子串简写这题,首先第一步就能想到一件事情:暴力枚举子串开头和末尾的位置,检查是否是符合题目要求的字符,如果是,并且长度大于......
  • 题解:AT_arc174_a [ARC174A] A Multiply
    题传。先要将\(C\)分类。\(C>0\),为了使答案更大,要乘上一个最大的区间和。\(C\le0\),为了使答案更大,选择乘上一个最小的区间和,因为此时我们可以贪心地想,如果区间和越小,乘上一个负数或\(0\)后,答案减少得越小,甚至乘上负数,还会使答案增大,所以也可以用负负得正来解释。当......
  • P8756 [蓝桥杯 2021 省 AB2] 国际象棋 题解
    设计状态什么的就不讲了,这里是对其它题解的优化。怎么优化呢,我们可以知道的是我们只要明确了当前行的状态,上一行的可选集就是知道的,如果我们明确了当前行以及上一行的状态,那么上上行的可选集就是知道的,于是我们就可以使用二进制子集枚举来写,这样就减去了全部不合法的枝叶,我们可以......