[TJOI2011] 书架(线段数优化dp + 单调栈)

problem

luogu-P1295

首先可以列出一个暴力 dpdpdp 转移。

f(i):f(i):f(i):iii 为止划分若干组,每组最大值的和 的最小值。

然后枚举最后一组,即 iii 所在组的开头 jjj,则 f(i)=min⁡{f(j−1)+max⁡j≤k≤i{ak}}f(i)=\min\Big\{f(j-1)+\max_{j\le k\le i}\big\{a_k\big\}\Big\}f(i)=min{f(j1)+maxjki{ak}}

observation1:\text{observation1}:observation1: f(i)f(i)f(i) 的值随 iii 的增加不降。

observation2:\text{observation2}:observation2: max⁡j≤k≤i{ak}\max_{j\le k\le i}\{a_k\}maxjki{ak}jjj 的减小不降。

observation3:j\text{observation3}:jobservation3:j 的取值,因为 mmm 的限制,一定是段连续区间。我们可以用单调栈记录下 jjj 取值的最小位置记为 pip_ipi

而一段连续的区间中选取最小值转移,我们很容易想到线段树优化 dpdpdp

但这里似乎还要处理一下 max⁡\maxmax 这个麻烦的部分。

管他的,先把线段树建出来,然后对于 iii 而言,线段树上每个点 jjj 表示其做最后一组的开头时,前面所有组的最大值之和的最小值。

即线段树上每个点 jjj,都记录 f(j−1)f(j-1)f(j1)

对于 max⁡\maxmax 部分,因为其不降,我们可以找到最大的 jjj 满足 aj>aia_j>a_iaj>ai 的位置,不妨记为 gig_igi。这可以单调栈来做到。

也就是说,当 dpdpdp 枚举到 iii 后,线段数上 [gi+1,i][g_i+1,i][gi+1,i] 的位置做 jjj 转移时 max⁡\maxmax 部分的贡献都是 aia_iai 了。

这就是线段树的区间覆盖操作。

所以我们线段树上不仅可以记录 f(j−1)f(j-1)f(j1) 还可以记录其做转移时的 max⁡\maxmax 贡献,以及二者相加的最小值,随着 iii 的枚举,激活 f(i−1)f(i-1)f(i1),并区间覆盖 max⁡\maxmax 贡献即可。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define maxn 100005
int n, m;
int h[maxn], sum[maxn], g[maxn], p[maxn], f[maxn];
stack < int > s;
queue < int > q;namespace SGT {struct node { int ans, minf, tag; }t[maxn << 2];#define lson now << 1#define rson now << 1 | 1#define mid  (l + r >> 1)#define inf 0x7f7f7f7fvoid build( int now, int l, int r ) {t[now].ans = t[now].minf = t[now].tag = inf;if( l == r ) return;build( lson, l, mid );build( rson, mid + 1, r );}void pushup( int now ) {t[now].ans = min( t[lson].ans, t[rson].ans );t[now].minf = min( t[lson].minf, t[rson].minf );}void pushdown( int now ) {if( t[now].tag == inf ) return;t[lson].ans = t[lson].minf + t[now].tag;t[rson].ans = t[rson].minf + t[now].tag;t[lson].tag = t[rson].tag = t[now].tag;t[now].tag = inf;}void modify( int now, int l, int r, int L, int R, int val ) {if( R < l or r < L ) return;if( L <= l and r <= R ) {t[now].tag = val;t[now].ans = t[now].minf + val;return;}pushdown( now );modify( lson, l, mid, L, R, val );modify( rson, mid + 1, r, L, R, val );pushup( now );}void modify( int now, int l, int r, int pos ) {if( l == r ) { t[now].minf = f[l - 1]; return; }pushdown( now );if( pos <= mid ) modify( lson, l, mid, pos );else modify( rson, mid + 1, r, pos );pushup( now );}int query( int now, int l, int r, int L, int R ) {if( R < l or r < L ) return inf;if( L <= l and r <= R ) return t[now].ans;pushdown( now );return min( query( lson, l, mid, L, R ), query( rson, mid + 1, r, L, R ) );}
}signed main() {scanf( "%lld %lld", &n, &m );for( int i = 1;i <= n;i ++ ) scanf( "%lld", &h[i] );for( int i = 1;i <= n;i ++ ) sum[i] = sum[i - 1] + h[i];for( int i = 1;i <= n;i ++ ) {while( ! s.empty() and h[s.top()] <= h[i] ) s.pop();if( ! s.empty() ) g[i] = s.top();s.push( i );}for( int i = 1;i <= n;i ++ ) {while( ! q.empty() and sum[i] - sum[q.front() - 1] > m ) q.pop();if( ! q.empty() ) p[i] = q.front();else p[i] = i;q.push( i );}SGT :: build( 1, 1, n );for( int i = 1;i <= n;i ++ ) {SGT :: modify( 1, 1, n, i );SGT :: modify( 1, 1, n, g[i] + 1, i, h[i] );f[i] = SGT :: query( 1, 1, n, p[i], i );}printf( "%lld\n", f[n] );return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/316362.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Picture POJ - 1177(矩形周长并))

Picture POJ - 1177 题目&#xff1a; 多个矩阵相交在一起&#xff0c;问新图形的周长是多少 题解&#xff1a; 参考题解 周长分为两部分&#xff1a;横线和竖线 横线计算方法&#xff1a;现在总区间被覆盖的长度和上一次总区间被覆盖的长度之差的绝对值 那么我们只需要从…

聊一聊C# 8.0中的await foreach

很开心今天能与大家一起聊聊C# 8.0中的新特性-Async Streams,一般人通常看到这个词表情是这样.简单说,其实就是C# 8.0中支持await foreach.或者说,C# 8.0中支持异步返回枚举类型async Task<IEnumerable<T>>.好吧,还不懂?Good,这篇文章就是为你写的,看完这篇文章,你…

【学习笔记】同余最短路

同余最短路是用来解决一类 ∑i1naixi∈[L,R]\sum_{i1}^n a_ix_i\in[L,R]∑i1n​ai​xi​∈[L,R] 问题的方法。 其中 L,RL,RL,R 值非常大&#xff0c;而 nnn 不是很大&#xff0c;大概是接受 O(n2)O(n^2)O(n2) 的范围&#xff0c;xix_ixi​ 是自定义的系数。 先差分一下&#…

Codeforces Round #738 (Div. 2)

Codeforces Round #738 (Div. 2) 文章目录A题解&#xff1a;代码&#xff1a;B题意&#xff1a;题解&#xff1a;代码&#xff1a;C题意&#xff1a;题解&#xff1a;代码&#xff1a;D1题意&#xff1a;题解&#xff1a;代码:题号题目知识点AMocha and MathBMocha and Red and…

ASP.NET Core 实现带认证功能的Web代理服务器

引言最近在公司开发了一个项目&#xff0c;项目部署架构图如下&#xff1a;思路如图中文本所述&#xff0c;公司大数据集群不允许直接访问外网&#xff0c;需要一个网关服务器代理请求&#xff0c;本处服务器A就是边缘代理服务器的作用。通常技术人员最快捷的思路是在服务器A上…

[ZJOI2010] 排列计数(dp + 组合数)

problem luogu-P2606 solution 我们对 i−⌊i2⌋i-\lfloor\frac i2\rfloori−⌊2i​⌋ 远没有 i−2∗i,2∗i1i-2*i,2*i1i−2∗i,2∗i1 敏感&#xff0c;这其实就是个二叉树&#xff0c;而且是个小根堆。 每个点的值都小于左右儿子的值&#xff08;如果有左右儿子&#xff0…

Unfair contest(个人做法)

Unfair contest 题意&#xff1a; 两个人参赛&#xff0c;n个评委打分&#xff0c;去掉s个最高分&#xff0c;去掉t个最低分&#xff0c;剩下分求平均分&#xff0c;平均分大的获胜。你是第n个评委&#xff0c;此时已知前n-1个评委所打分数&#xff0c;现在轮到你打分&#x…

ASP.NET Core 进程外(out-of-process)托管(7)《从零开始学ASP.NET CORE MVC》

本文出自《从零开始学ASP.NET CORE MVC》推荐文章&#xff1a;ASP.NET Core 进程内(InProcess)托管ASP.NET Core 进程内(InProcess)托管我们先简单回顾下 ASP.NET Core 中,要配置InProcess的服务器&#xff0c;需要在项目文件中添加< AspNetCoreHostingModel >元素&#…

[CQOI2017] 老C的键盘(树形dp + 组合数)

problem luogu-P3757 solution observation:\text{observation}:observation: hi/2−hih_{i/2}-h_ihi/2​−hi​ 的大小关系&#xff0c;其实就是个二叉树的大小关系。 这很类似之前的排列 dpdpdp &#xff0c;迁移过来&#xff0c;我们尝试 f(i,j):if(i,j):if(i,j):i 在子树…

Educational Codeforces Round 112 (Rated for Div. 2)

Educational Codeforces Round 112 (Rated for Div. 2) 题号题目知识点APizzaForcesBTwo TablesCCoin RowsDSay No to PalindromesEBoring Segments尺取线段树FGood GraphLCT(未补)

eShopOnContainers 知多少[10]:部署到 K8S | AKS

1. 引言断断续续&#xff0c;感觉这个系列又要半途而废了。趁着假期&#xff0c;赶紧再更一篇&#xff0c;介绍下如何将eShopOnContainers部署到K8S上&#xff0c;进而实现大家常说的微服务上云。2. 先了解下 Helm读过我上篇文章ASP.NET Core 借助 K8S 玩转容器编排的同学&…

[HEOI2013] SAO(dp + 组合数 + 前缀和)

problem luogu-P4099 solution 两篇前提题解&#xff1a;排列计数&#xff0c;老C的键盘 想必已经看了 CQOI2017 老C的键盘 一题题解了。 这里直接考虑优化状态转移方程。 我们发现 f(u,i),f(v,j)f(u,i),f(v,j)f(u,i),f(v,j)&#xff0c;当枚举 jjj 后&#xff0c;对应的…

cf1555A. PizzaForces

cf1555A. PizzaForces A. PizzaForces 题意&#xff1a; 有三种披萨&#xff0c;第一种有六块&#xff0c;需要花费15分钟&#xff0c;第二种有8块&#xff0c;需要花费20分钟&#xff0c;第三问有10块&#xff0c;需要花费25分钟。 现在要吃x块披萨&#xff0c;问最少时间花…

DI是实现面向切面和面向抽象的前提

DI越来越重要DI就是依赖注入&#xff0c;现在来说&#xff0c;大部分框架都是以DI为基础组件的&#xff0c;每一个框架都有自己的DI组件&#xff0c;像dotnet core&#xff0c;java spring等&#xff0c;也都为自己的框架量身打造了DI工具。面向对象的几个原则依赖倒置原则&…

[CQOI2017] 老C的任务(差分 + 树状数组 / K-D tree)

problem luogu-P3755 solution 这题第一眼矩阵内的点权值和&#xff0c;马上就是 K-D tree\text{K-D tree}K-D tree 不过脑子的敲。 这其实就是个二维数点问题&#xff0c;完全可以树状数组。 将矩阵差分成四个以原点为左下角的矩阵。 然后将基站按 xxx 轴排序&#xff0…

.net core 并发下的线程安全问题

抱歉&#xff0c;其实内容并不如题&#xff01;&#xff01;&#xff01;背景&#xff08;写测试demo所出现的异常&#xff0c;供大家学习与拍砖&#xff09;&#xff1a;.net core webapi项目&#xff0c;做了一个授权的filter&#xff08;真正的生产项目的话&#xff0c;JWT很…

cf1555B. Two Tables

cf1555B. Two Tables 题意&#xff1a; 一个大矩阵空间内放置一个矩阵a&#xff0c;现在要再往这个空间内放一个矩阵b&#xff0c;a移动距离len才能放下b&#xff0c;问len最小是多少 题解&#xff1a; 不难发现左右或上下移动是最佳的&#xff0c;斜着移动是最不好的。此时…

cf1555C Coin Rows

cf1555C Coin Rows 题意&#xff1a; 有一个两行m列的地图&#xff0c;每个格子都有对应的价值&#xff0c;有a&#xff0c;b两个人&#xff0c;都从左上角到右下角&#xff0c;且都只能向右向下走&#xff0c;a先出发&#xff0c;a每到一个格子&#xff0c;就会获得这个地方…

C#并行编程(2):.NET线程池

线程 Thread在总结线程池之前&#xff0c;先来看一下.NET线程。.NET线程与操作系统(Windows)线程有什么区别&#xff1f;.NET利用Windows的线程处理功能。在C#程序编写中&#xff0c;我们首先会新建一个线程对象System.Threading.Thread&#xff0c;并为其指定一个回调方法&…

[CQOI2015] 任务查询系统(主席树)

problem luogu-P3168 solution 主席树板题。 将一个任务拆成 lil_ili​ 秒开始&#xff0c;ri1r_i1ri​1 秒结束的两个任务。 但不建议以每一秒作为一个主席树版本&#xff0c;因为一秒中可能有若干个任务开始或结束。 不妨将所有任务按时刻排序&#xff0c;然后以每个任…