LOJ#6032. 「雅礼集训 2017 Day2」水箱【笛卡尔树】

2024-02-25 01:50

本文主要是介绍LOJ#6032. 「雅礼集训 2017 Day2」水箱【笛卡尔树】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目描述:

在这里插入图片描述
在这里插入图片描述

题目分析:

如果想象水慢慢往上涨,高的隔板会将不同的区域分隔开,导致两边的水位高低可能不一样。
而水位如果超过了隔板,那么这个隔板两边就等价了。
于是我们想到用最大值将区间划分,然后答案就可以这么求(设当前隔板的高度为h,最近的比当前隔板高的隔板的高度为h’):
如果水位没有达到当前隔板,可以满足的条件为h到h’中无水的条件加上当前隔板两边水位任意时最多满足的条件。
如果水位达到了当前隔板,可以满足的条件为h到当前水位中有水的条件加上当前水位到h’中无水的条件加上隔板两边水满时能够满足的条件。

这样笛卡尔树的树形DP的模型就很容易看出来了。
在这里插入图片描述

还有一个实现的细节就是怎么知道条件在笛卡尔树中哪一个点的管辖范围内。
可以尝试由小到大枚举隔板的高度,初始化L[i]=R[i]=i,将高度小于条件高度的隔板删去(令L[i]=i-1,R[i]=i+1),然后并查集查找到高度大于条件的最近的隔板,他在笛卡尔树上的左儿子或右儿子就是我们要找的点。
也可以尝试从条件的横坐标对应的笛卡尔树上的节点在树上倍增,找到最后一个高度<=条件的点即可。

Code:

#include<bits/stdc++.h>
#define maxn 200005
#define maxp maxn*17
#define maxm maxp*6
using namespace std;
char cb[1<<18],*cs,*ct;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<18,stdin),cs==ct)?0:*cs++)
inline void read(int &a){char c;while(!isdigit(c=getc()));for(a=c-'0';isdigit(c=getc());a=a*10+c-'0');
}
const int Log = 16;
int n,m,tot,h[maxn],S[maxn],tp,f[maxn][Log+1],pos[maxn],dp[maxn][2];
int rt,lc[maxn],rc[maxn];
vector<pair<int,int> >G[maxn];
void dfs0(int &u,int ff){if(!u) tot++,pos[tot]=u=n+tot-1;//single point, middle implementation 1~nf[u][0]=ff;for(int i=1;i<=Log;i++) f[u][i]=f[f[u][i-1]][i-1];if(u<n) dfs0(lc[u],u),dfs0(rc[u],u);
}
void dfs(int u){if(!u) return;dfs(lc[u]),dfs(rc[u]);sort(G[u].begin(),G[u].end());int s0=0,s1=0;for(auto i:G[u]) if(!i.second) s0++;dp[u][0]=dp[lc[u]][0]+dp[rc[u]][0]+s0;for(auto i:G[u]){i.second?s1++:s0--;dp[u][0]=max(dp[u][0],dp[lc[u]][1]+dp[rc[u]][1]+s1+s0);}dp[u][1]=dp[lc[u]][1]+dp[rc[u]][1]+s1;
}
int main()
{int Test,x,y,k;read(Test);while(Test--){read(n),read(m),tp=tot=0;for(int i=1;i<2*n;i++) G[i].clear(),lc[i]=rc[i]=0;for(int i=1;i<n;i++){read(h[i]);while(tp&&h[i]>=h[S[tp]]) lc[i]=S[tp--];if(tp) rc[S[tp]]=i; S[++tp]=i;}dfs0(S[1],0);while(m--){read(x),read(y),read(k),x=pos[x];for(int i=Log;i>=0;i--) if(f[x][i]&&h[f[x][i]]<=y) x=f[x][i];G[x].push_back(make_pair(y,k));}dfs(S[1]);printf("%d\n",dp[S[1]][0]);}
}

这篇关于LOJ#6032. 「雅礼集训 2017 Day2」水箱【笛卡尔树】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/744078

相关文章

Java预备知识 - day2

1.IDEA的简单使用与介绍 1.1 IDEA的项目工程介绍 Day2_0904:项目名称 E:\0_code\Day2_0904:表示当前项目所在路径 .idea:idea软件自动生成的文件夹,最好不要动 src:src==sourse→源,我们的源代码就放在这个文件夹之内 Day2_0904.iml:也是自动生成的文件,不要动 External Libraries:外部库 我这

2014暑假集训搜索专题

A - 漫步校园 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Description LL最近沉迷于AC不能自拔,每天寝室、机房两点一线。由于长时间坐在电脑边,缺乏运动。他决定充分利用每次从寝室到机房的时间,在校园里散散步。整个HDU校园呈方形布局,可划

2017 版本的 WebStorm 永久破解

1.  在IntelliJ官网中下载 最新版本的WebStorm   下载地址:https://www.jetbrains.com/webstorm/download/#section=windows 2. 获取注册码    获取地址:http://idea.lanyus.com/   点击获取注册码,然后将注册码复制,再打开最新版的WebStorm,将注册码粘贴到激活框中就大功告

【为项目做准备】Linux操作系统day2

这两天学校的事情总压着,day2拖了好几天..day2内容是进程数据结构 进程数据结构信号处理任务状态进程调度运行统计信息进程亲缘关系进程权限用户和组标识符(IDs)linux capabilities 内存管理文件与文件系统用户态与内核态用户态与内核态的转换函数调用栈内核栈和task_struct的关系 进程数据结构 进程or线程,在内核中,统一叫任务(Task),由一个统

Android智能家居实训day2

设置使用的布局文件 setContentView(R.layout.filename);,之后使用布局嵌套,一个布局内部可以嵌套另一个布局,内部的布局相当于外部布局的一个子控件,可以把它当作一个整体来操作,例如在今天的八宫格使用布局嵌套的时候,每一个格子是一个线性布局布局内使用垂直方向,而每两个布局作为一行,一共四行,这样就再拿一个布局框起来使用水平方向最后再把这四个布局用垂直方向。在布局之间分配

寒假集训第二天——线性表

现在时间是北京时间1点23分,第二天集训。。。 昨天花了老长时间把线性表看了下,表示很有压力,不大会用。。。 先说下我学到的线性表的皮毛。。。 首先是链表的构建,构建有两种方式: 顺序链表(尾插法建单链表) #include<stdio.h>struct node{int date;struct node *next;};int main(){int i,n;node *he

寒假集训第一天——结构体

期待已久的寒假集训终于开始了,第一天讲的内容比较简单——结构体,之前就学了点。。。 表示普通的结构体会用,涉及到指针都不大会,今天算是学了点指针的用法。。。 作业描述如下: 结构体 今天作业  1.定义一个acmer结构体,包括以下信息:姓名,学号,手机号,做题数,出生日期,其中出生日期date也是一个结构体,包括年、月、日  2.建立结构体数组,实现对多个同学

寒假集训——字典树(模板)

struct node{int v;node *next[26];} T[1000000];int t=0;node *newnode(){node *p=new node;//动态分配//node *p=&T[t++];//静态分配p->v=0;for(int i=0; i<26; i++)p->next[i]=NULL;return p;}void insertnode(node

寒假集训——二叉树

#include <iostream>#include <stdio.h>#include <string.h>#include <queue>using namespace std;typedef struct node{char date;node *lch,*rch;}Bn,*Bt;void cbtree(Bt &T)//先序建二叉树{char c;scanf("%c"

网易2017秋招编程题集合--完全解析

前言 一些大公司的真题里面总有些含金量很高的几个题,网易2017秋招编程题集合里面也有几个题是非常好的,比如说第三题跳石板,第四题黑暗的字符串都是很好的题目。特别是第四题的那种思路之前几乎完全没有接触过,还有第六题最大的奇约数里面还有部分数学思维在里面。 1.回文序列 题目描述:如果一个数字序列逆置之后跟原序列是一样的就称这样的数字序列为回文序列。例如: {1, 2, 1}, {15, 7