YbtOJ#463-序列划分【二分答案,线段树,dp】

正题

题目链接:https://www.ybtoj.com.cn/problem/463


题目大意

给出长度为nnn的序列A,BA,BA,B。要求划分成若干段满足

  1. 对于任何i<ji<ji<j,若iiijjj不是同一段的,要求满足Bi>AjB_i>A_jBi>Aj
  2. 每一段AiA_iAi的最大值的和不能超过mmm

要求最小化每一段BiB_iBi和的最大值。

n∈[1,105],Ai,Bi∈[1,109],m∈[1,1012]n\in[1,10^5],A_i,B_i\in[1,10^9],m\in[1,10^{12}]n[1,105],Ai,Bi[1,109],m[1,1012]


解题思路

最大值最小化很显然直接二分,然后变为求每一段AiA_iAi最大值的和的最小值。

第一个条件相当于限制了什么位置能够作为划分段的末尾,求一个前缀min{bi}min\{b_i\}min{bi}和一个后缀max{ai}max\{a_i\}max{ai}能够快速求出这些位置。

然后考虑dpdpdp,转移方程就是
fi=min{fj+max{ak}(k∈(j,i])}f_i=min\{f_j+max\{a_k\}(\ k\in(j,i]\ )\}fi=min{fj+max{ak}( k(j,i] )}

二分的条件限制了jjj的范围,加个指针就好了

这个东西好像很难搞,但是注意到vj=max{ak}v_j=max\{a_k\}vj=max{ak}这一部分是递减的,并且每次会让所有viv_ivi的一起和一个一起取maxmaxmax

因为是递减的,所以每次加入一个新的就相当于修改一段后缀的viv_ivi,然后求一个区间的最大fi+vif_i+v_ifi+vi了。

可以线段树维护,每个节点维护该区间最大的fi+vif_i+v_ifi+vi和最大的fif_ifi。区间推平viv_ivi的时候就可以拿最大的fif_ifi来更新fi+vif_i+v_ifi+vi

时间复杂度O(nlog⁡nlog⁡∑bi)O(n\log n\log\sum b_i)O(nlognlogbi)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=1e5+10,inf=1e9+7;
ll n,m,a[N],b[N],pre[N],suf[N],last[N];
ll lg[N],st[N][17],v[N<<2],w[N<<2],lazy[N<<2];
void Downdata(ll x){if(!lazy[x])return;lazy[x*2]=lazy[x*2+1]=lazy[x];w[x*2]=v[x*2]+lazy[x];w[x*2+1]=v[x*2+1]+lazy[x];lazy[x]=0;return;
}
void Changew(ll x,ll L,ll R,ll l,ll r,ll val){if(l>r)return;if(L==l&&R==r){w[x]=v[x]+val;lazy[x]=val;return;}ll mid=(L+R)>>1;Downdata(x);if(r<=mid)Changew(x*2,L,mid,l,r,val);else if(l>mid)Changew(x*2+1,mid+1,R,l,r,val);else Changew(x*2,L,mid,l,mid,val),Changew(x*2+1,mid+1,R,mid+1,r,val);w[x]=min(w[x*2],w[x*2+1]);
}
void Changev(ll x,ll l,ll r,ll pos,ll val){if(l==r){v[x]=val;w[x]=v[x]+lazy[x];return;}ll mid=(l+r)>>1;Downdata(x);if(pos<=mid)Changev(x*2,l,mid,pos,val);else Changev(x*2+1,mid+1,r,pos,val);w[x]=min(w[x*2],w[x*2+1]);v[x]=min(v[x*2],v[x*2+1]);return;
}
ll Ask(ll x,ll L,ll R,ll l,ll r){if(L==l&&R==r)return w[x];ll mid=(L+R)>>1;Downdata(x);if(r<=mid)return Ask(x*2,L,mid,l,r);if(l>mid)return Ask(x*2+1,mid+1,R,l,r);return min(Ask(x*2,L,mid,l,mid),Ask(x*2+1,mid+1,R,mid+1,r));
}
ll RMQ(ll l,ll r){ll z=lg[r-l+1];return max(st[l][z],st[r-(1<<z)+1][z]);
}
bool check(ll x){memset(v,0x3f,sizeof(v));memset(w,0x3f,sizeof(w));memset(lazy,0,sizeof(lazy));ll sum=0,l=0,tmp=v[0];Changev(1,0,n,0,0);for(ll i=1;i<=n;i++){sum+=b[i];while(sum>x)l++,sum-=b[l];Changew(1,0,n,last[i],i-1,a[i]);if(pre[i]<=suf[i+1])continue;tmp=Ask(1,0,n,l,i);Changev(1,0,n,i,tmp);}return (tmp<=m);
}
signed main()
{freopen("sequence.in","r",stdin);freopen("sequence.out","w",stdout);scanf("%lld%lld",&n,&m);ll l=1,r=0;pre[0]=inf;for(ll i=1;i<=n;i++)scanf("%lld%lld",&a[i],&b[i]),r+=b[i],l=max(l,b[i]),st[i][0]=a[i];for(ll i=2;i<=n;i++)lg[i]=lg[i>>1]+1;for(ll j=1;(1<<j)<=n;j++)for(ll i=1;i+(1<<j)-1<=n;i++)st[i][j]=max(st[i][j-1],st[i+(1<<j-1)][j-1]);for(ll i=1;i<=n;i++){ll l=1,r=i-1;while(l<=r){ll mid=(l+r)>>1;if(RMQ(mid,i)>a[i])l=mid+1;else r=mid-1;}last[i]=r;}for(ll i=1;i<=n;i++)pre[i]=min(pre[i-1],b[i]);for(ll i=n;i>=1;i--)suf[i]=max(suf[i+1],a[i]);while(l<=r){ll mid=(l+r)>>1;if(check(mid))r=mid-1;else l=mid+1;}check(l+1);printf("%lld\n",l);
}

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

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

相关文章

微软技术大会预览:DevOps顾问是怎样开发自己的产品的

“没有人比我们更懂DevOps”&#xff0c;这句话不是谁都敢说的。从无人问津到整个IT行业趋之若鹜&#xff0c;DevOps火起来也不过是3年的事情&#xff0c;但是leansoftX.com的DevOps资深顾问都是在这个行业已经摸爬滚打了10年的老兵了&#xff0c;从一开始的SDLC&#xff0c;到…

【双指针】Square Pasture G(P7153)

正题 P7153 题目大意 给你平面上的若干点&#xff0c;让你画一个正方形&#xff0c;问框住的点有多少种组合 解题思路 先枚举正方形左右两边的点&#xff0c;然后用双指针计算正方形移动过程中1框住的点 然后把所有点x,y坐标取反&#xff0c;再做一次&#xff0c;这样可以把…

Neat Tree

Neat Tree 题意&#xff1a; n个数&#xff0c;每个区间的贡献为区间内最大值减最小值&#xff0c;问这个n个数的总贡献是多少&#xff1f;也就是n所能组成的所有区间的贡献值之和 题解&#xff1a; 我们可以用单调栈来做 第i个数对答案的贡献值为h[i] * 作为最大值出现的次…

PEACHPIE 0.9.11 版本发布,可以上生产了

PeachPie在官方博客&#xff08;https://www.peachpie.io/2018/10/release-0911-visual-studio.html&#xff09;发布了PeachPie的0.9.11版本 - 用于.NET和.NET Core的PHP编译器和运行时。此更新为项目管理引入了许多新功能&#xff0c;兼容性增强和改进。0.9.11是第一个非预览…

YbtOJ#573-后缀表达【二分图匹配】

正题 题目链接:https://www.ybtoj.com.cn/contest/115/problem/2 题目大意 给出一个包含字母变量和若干种同级操作符的后缀表达式。求一个等价的表达式满足该表达式的连续相同段最少。 1≤∣S∣≤25001\leq |S|\leq 25001≤∣S∣≤2500 解题思路 构建出表达树先&#xff0c;…

【DP】Sleeping Cows P(P7154)

正题 P7154 题目大意 有n头牛和n个牛棚&#xff0c;每头牛可以进入体积大于等于该牛的牛棚&#xff0c;当一个所有未进入牛棚的牛都不能再进时&#xff0c;称为极大的匹配&#xff0c;问你有多少种极大的匹配 解题思路 先把牛棚和牛放到一起&#xff0c;然后按体积排序 那么…

[ZJOI2007]棋盘制作

文章目录[ZJOI2007]棋盘制作题意&#xff1a;题解&#xff1a;单调栈代码&#xff1a;悬线法[ZJOI2007]棋盘制作 题意&#xff1a; 选取最大的01相邻的正方形和矩形&#xff0c;输出面积 题解&#xff1a; 单调栈 如图&#xff1a; 左图为题目给的样例&#xff0c;我们要找…

.net core实践系列之SSO-同域实现

前言SSO的系列还是以.Net Core作为实践例子与大家分享&#xff0c;SSO在Web方面复杂度分同域与跨域。本篇先分享同域的设计与实现&#xff0c;跨域将在下篇与大家分享。如有需要调试demo的&#xff0c;可把SSO项目部署为域名http://sso.cg.com/&#xff0c;Web1项目部署为http:…

牛客练习赛 56 E tarjan 割边

A - 小蒟和他的乐谱 签到题&#xff0c;将原序列对 7 取模之后将序列扫描一遍就可以得到答案 不过感觉题目意思还需要理解理解 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<set> #include<map> #include<…

YbtOJ#903-染色方案【拉格朗日插值,NTT,分治】

正题 题目链接:https://www.ybtoj.com.cn/contest/115/problem/3 题目大意 两个长度为n1n1n1的序列a,ba,ba,b aia_iai​表示涂了iii个格子的可以获得的价值。 bib_ibi​表示恰好用iii种颜色图最多nnn个格子可以获得的总价值。 给出序列bbb&#xff0c;求序列aaa n∈[1,105]n…

【并查集】封锁阳光大学(P1330)

正题 P1330 题目大意 给你一张无向图&#xff0c;问你最少选择多少个点&#xff0c;使得每一条边都有且只有一个端点被选择 解题思路 每一条边只能选一个点&#xff0c;那么考虑对这个图黑白染色 可以用扩展域并查集判二分图&#xff0c;然后两边的点选小的就好了 code #i…

【悬线法】学习总结

【悬线法】学习总结 主要用于求满足某条件的最大矩阵 定义&#xff1a; 一条竖线&#xff0c;竖线的上端点位于矩阵的上边界或是一个障碍点&#xff0c;然后对这条悬线进行左右移动&#xff0c;直到移至障碍点或者是矩阵边界&#xff0c;进行确定这条悬线所在的极大矩阵。 底…

开源硬件论坛,燃烧你的创造力

写在大会前开源融合&#xff1a;比特与原子开源硬件延伸着开源软件的理念&#xff0c;包括硬件设计文件及基于此文件的产品都使用具有开源性质的许可协议&#xff0c;自由使用分享。虽然&#xff0c;从仅开放硬件所配套软件到对硬件本身设计也进行开放的过程&#xff0c;曾经一…

牛客练习赛 55

A - 等火车 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<set> #include<map> #include<cmath> #include<queue> #include<string> #include<vector> #include<cstdio> #inclu…

CF618F-Double Knapsack【结论】

正题 题目链接:https://www.luogu.com.cn/problem/CF618F 题目大意 给出大小为nnn&#xff0c;值域为[1,n][1,n][1,n]的两个可重集合A,BA,BA,B 需要你对它们各求出可重子集使得两个子集中的数字和相等 输出方案。 1≤n≤1061\leq n\le 10^61≤n≤106 解题思路 这个值域范围…

【LCT】遥远的国度(P3979)

正题 P3979 题目大意 给你一棵树&#xff0c;让你进行一下操作&#xff1a; 把根节点修改为x把x到y路径上的点权值修改为v查询x子树中的最小权值 解题思路 可以用LCT维护该树 查询时先make_root(rt)make\_root(rt)make_root(rt)&#xff0c;然后把x旋转到rt的儿子&#xf…

单调栈讲解

以前一直有接触&#xff0c;但是一直没单独进行分析处理 单调栈&#xff1a;维护其中元素单调性的栈 也就是从栈底到栈顶都是有序的 维护&#xff1a;如果入栈的元素满足单调性&#xff0c;直接入栈&#xff1b;如果不满足&#xff0c;就让栈顶元素出栈&#xff0c;直到能让入栈…

【深圳(活动)】70多场干货分享!价值899元的2018中国开源年会门票等你认领

开源发展20年&#xff0c;.NET Core开源 4年时间&#xff0c;.NET开源实现Mono也有18年的时间&#xff0c;特别近年国内.NET Core社区的蓬勃发展&#xff0c;.NET Core中国社区作为中国开源社区的重要参与者&#xff0c;获得官方的优惠票. 活动主办方开源社&#xff0c;为.NET …

2019-2020 ICPC Asia Hong Kong Regional Contest 补题(部分)

codeforces原题链接 大佬题解 B - Binary Tree 每个人每次一定拿走奇数&#xff08;2k−12^k-12k−1&#xff09;个节点&#xff0c;如果先手必胜不难发现两人轮流拿最终一定拿奇数次&#xff08;每次奇数个节点&#xff09;说明一共有奇数个节点&#xff0c;如果先手必败说明…

YbtOJ#526-折纸游戏【二分,hash】

正题 题目链接:https://www.ybtoj.com.cn/problem/526 题目大意 一个nmn\times mnm的网格上有字母&#xff0c;你每次可以沿平行坐标轴对折网格&#xff0c;要求对折的对应位置字母相同。 询问有多少个可能对折出来的子矩阵。 1≤nm≤1061\leq n\times m\leq 10^61≤nm≤106…