题解:SP6517 JOCHEF - Farmer Sepp
怎么题解全是 dp?可以用笛卡尔树啊!
题目传送门。
笛卡尔树的介绍
笛卡尔树,是一种二叉搜索树,它满足如下条件:
- 每个节点的编号满足二叉搜索树的性质。
- 每个节点的权值满足小根堆或大根堆的性质。
大概是这个样子:

笛卡尔树的建树
笛卡尔树的用途
它可以用来解决区间最值问题,它有一个重要性质:当这个笛卡尔树为小根堆时,\(\min_{i = l}^r a_i = a_{\operatorname{lca}(l,r)}\),当这个笛卡尔树为大根堆时,\(\max_{i = l}^r a_i = a_{\operatorname{lca}(l,r)}\)。
所以,我们要求一个区间的最小值,只需将笛卡尔树建成小根堆的样式,按照性质求,如果要求一个区间的最大值,只需将笛卡尔树建成大根堆的样式,按照性质求。
当然,它还可以求有多少个区间的最小值或最大值为 \(a_i\),只需看有对少对区间的两端点的最近公共祖先是 \(i\) 即可,由于要使 \(\operatorname{lca}(l,r) = i\),那么 \(l\) 肯定在 \(i\) 的左子树或是 \(i\),\(r\) 肯定在 \(i\) 的右子树或是 \(i\),所以,设 \(s_i\) 表示 \(i\) 这个子树的大小,\(l_i\) 表示 \(i\) 的左儿子,\(r_i\) 表示 \(i\) 的右儿子,则就有 \((s_{l_i}+1) \times (s_{r_i}+1)\) 对区间的两端点的最近公共祖先为 \(i\)。
此题做法
首先使用前缀和将每个位置往上有多少个连续的 H,设这个数组为 \(f\)。
我们枚举每一行的每个位置。
然后放个假设图(其中一行):

图可能有点丑,请谅解(感谢)!!
假设这是第 \(k\) 行的 \(f\) 数组情况,其中第 \(i\) 个柱子的高度是 \(f_{k,i}\) 对于这第 \(k\) 行,如果要使矩阵的高为第二个柱子,那么它必须得找高度比它高或相等的柱子拼起来才行,所以得找到最左边的一个柱子 \(j\),使得 \(j \le i\) 并且从 \(j\) 到 \(i\) 这些柱子的高度都大于等于等于柱子 \(i\) 的高度,那么这个 \(j\) 就是高为第 \(i\) 个柱子的矩形的左端点,然后再找到 \(k\),使得 \(k<i\) 并且从 \(i\) 到 \(k\) 这些柱子的高度都大于等于等于柱子 \(i\) 的高度,那么这个 \(k\) 就是高为第 \(i\) 个柱子的矩形的右端点,到这里大家都知道可以用单调栈做了吧,但是,我们是要用笛卡尔树的,所以还没完。实际上我们就是要找到区间长度最大的 \([j,k]\),使得 \(\min_{q = j}^k a_q = a_i\),那么就变成了上面说的笛卡尔树的用途的变形,由于我们要使 \([j,k]\) 的长度最大并且满足要求,那么 \(j\) 一定是 \(i\) 的左子树中编号最小的数(如果 \(i\) 没有左子树,那 \(j = i\)),\(k\) 一定是 \(i\) 的右子树中编号最大的数(如果 \(i\) 没有右子树,那 \(k = i\)),这样才能使 \([j,k]\) 长度最大且满足条件,知道了 \([j,k]\) 的长度之后,直接拿长度乘上当前柱子就是以当前柱子为高的最大矩形面积。然后求一个子树中编号最小的数和编号最大的数只需找到笛卡尔树的根,然后搜索一下,递推即可。
讲的这么详细,放个代码没问题吧:
#include<bits/stdc++.h>
using namespace std;
const int N = 4e3+5;
char a[N][N];
int q[N];
int f[N][N];
int l[N];
int r[N];
int depmax[N];
int depmin[N];
int num[N];
//计算depmax,depmin
void dfs(int x)
{
depmax[x] = x;
depmin[x] = x;
if(l[x])
{
dfs(l[x]);
depmin[x] = min(depmin[x],depmin[l[x]]);
depmax[x] = max(depmax[x],depmax[l[x]]);
}
if(r[x])
{
dfs(r[x]);
depmin[x] = min(depmin[x],depmin[r[x]]);
depmax[x] = max(depmax[x],depmax[r[x]]);
}
}
int main()
{
while(1)
{
memset(f,0,sizeof(f));
memset(num,0,sizeof(num));
int n,m,k;
scanf("%d %d",&n,&m);
if(!n&&!m)
{
return 0;
}
scanf("%d",&k);
for(int i = 1;i<=n;i++)
{
scanf("%s",a[i]+1);
}
//求前缀和f
for(int i = 1;i<=n;i++)
{
for(int j = 1;j<=m;j++)
{
if(a[i-1][j] == 'H'&&a[i][j] == 'H')
{
f[i][j] = f[i-1][j]+(a[i][j] == 'H');
}
else if(a[i][j] == 'H')
{
f[i][j] = 1;
}
}
}
int maxx = 0;
for(int i = 1;i<=n;i++)
{
//建树
memset(l,0,sizeof(l));
memset(r,0,sizeof(r));
int t = 0;
for(int j = 1;j<=m;j++)
{
while(t&&f[i][q[t]]>f[i][j])
{
l[j] = q[t];
t--;
}
if(t)
{
r[q[t]] = j;
}
q[++t] = j;
}
//找根
for(int j = 1;j<=m;j++)
{
num[l[j]] = i;//记录下这个点有父亲
num[r[j]] = i;//记录下这个点有父亲
}
for(int j = 1;j<=m;j++)
{
if(num[j]!=i)//如果这个点没有父亲
{
dfs(j);
break;
}
}
//计算
for(int j = 1;j<=m;j++)
{
int ll,rr;
if(l[j])
{
ll = min(depmin[l[j]],j);
}
else
{
ll = j;
}
if(r[j])
{
rr = max(depmax[r[j]],j);
}
else
{
rr = j;
}
maxx = max(maxx,(rr-ll+1)*f[i][j]);
}
}
printf("%lld\n",1ll*maxx*k);
}
return 0;
}
题解:SP6517 JOCHEF - Farmer Sepp的更多相关文章
- usaco training 4.2.2 The Perfect Stall 最佳牛栏 题解
The Perfect Stall题解 Hal Burch Farmer John completed his new barn just last week, complete with all t ...
- usaco training 4.1.1 麦香牛块 题解
Beef McNuggets题解 Hubert Chen Farmer Brown's cows are up in arms, having heard that McDonalds is cons ...
- POJ 3279(Fliptile)题解
以防万一,题目原文和链接均附在文末.那么先是题目分析: [一句话题意] 给定长宽的黑白棋棋盘摆满棋子,每次操作可以反转一个位置和其上下左右共五个位置的棋子的颜色,求要使用最少翻转次数将所有棋子反转为黑 ...
- usaco training 4.1.3 fence6 题解
Fence Loops题解 The fences that surround Farmer Brown's collection of pastures have gotten out of cont ...
- usaco training 4.1.2 Fence Rails 题解
Fence Rails题解 Burch, Kolstad, and Schrijvers Farmer John is trying to erect a fence around part of h ...
- usaco training 3.4.3 fence9 题解
Electric Fence题解 Don Piele In this problem, `lattice points' in the plane are points with integer co ...
- usaco 2002 月赛 Fiber Communications 题解
Description Farmer John wants to connect his N (1 <= N <= 1,000) barns (numbered 1..N) with a ...
- 洛谷P2891 Dining P1402 酒店之王【类二分图匹配】题解+代码
洛谷P2891 Dining P1402 酒店之王[类二分图匹配]题解+代码 酒店之王 题目描述 XX酒店的老板想成为酒店之王,本着这种希望,第一步要将酒店变得人性化.由于很多来住店的旅客有自己喜好的 ...
- 题解——洛谷P1550 [USACO08OCT]打井Watering Hole(最小生成树,建图)
题面 题目背景 John的农场缺水了!!! 题目描述 Farmer John has decided to bring water to his N (1 <= N <= 300) pas ...
- Codeforces Round #102 (Div. 1) A. Help Farmer 暴力分解
A. Help Farmer 题目连接: http://www.codeforces.com/contest/142/problem/A Description Once upon a time in ...
随机推荐
- COSBrowser 文件夹分享——多端文件实时共享
您还在为临时分享某个文件夹而烦恼吗? 您是否对授权的复杂度感到震惊? 关于存储桶 Policy 权限,您是否很迷茫,不知如何设置? 不用着急,用 COSBrowser 开始文件夹分享,一键简化分享 ...
- Flutter ListView顶部空白去除
Flutter ListView顶部空白去除 当listview没有和AppBar一起使用时,顶部会有一个自动的空白部分,可以用MediaQuery.removePadding去掉 return Me ...
- 【C#】【报错解决】分析器错误消息: 无法识别的属性“targetFramework”。请注意属性名称区分大小写。
服务器:Windows Server 数据中心 2016 问题描述: 在本地测试正常运行,但是上传到服务器却出现该错误 报错: 分析器错误消息: 无法识别的属性"targetFramewor ...
- Qt编写地图综合应用33-雨量分布
一.前言 雨量分布图是在区域地图基础上,针对区域中的每个最小单位区域比如县城点位不同颜色显示,最开始做这个封装的时候,并没有提供单独设置每个点颜色的接口,后面经过几个客户的强烈建议,咬咬牙把每个点都可 ...
- Qt音视频开发17-海康sdk解码
一.前言 在视频监控行业领域,海康当之无愧是老大,稳坐第一的宝座很多年了,近期需要将视频监控系统改成采用海康sdk的内核,于是特意去查阅了sdk的使用手册,sdk相关的文档和文件可以直接官网下载到,而 ...
- 饿了么组件中el-menu el-submenu el-menu-item三者之间的关系
饿了么组件中el-menu el-submenu el-menu-item三者之间的关系: 1.<el-menu>是菜单标签,里面可以包括:<el-submenu>和&l ...
- CDS标准视图:维护活动类型描述 I_MaintenanceActivityTypeText
视图名称:维护活动类型描述 I_MaintenanceActivityTypeText 视图类型:基础 视图代码: 点击查看代码 @AbapCatalog.sqlViewName: 'IMTACTTY ...
- WPF刮刮乐
WPF刮刮乐 <Window x:Class="WpfApp2.MainWindow" xmlns="http://schemas.microsoft.com/wi ...
- RestTemplate 详解
RestTemplate 简介 RestTemplate 是从 Spring3.0 开始支持的一个 HTTP 请求工具,它提供了常见的REST请求方案的模版,例如 GET 请求.POST 请求.PUT ...
- nginx平台初探-2
handler模块简介 相信大家在看了前一章的模块概述以后,都对nginx的模块有了一个基本的认识.基本上作为第三方开发者最可能开发的就是三种类型的模块,即handler,filter和load-ba ...