【IOI2018】会议【笛卡尔树】【dp】【线段树】

题意:长度为nnn的序列,qqq次询问,每次给定一个区间,钦定区间中的一个位置xxx,使得区间所有点 与xxx之间的最大值(含端点) 之和 最小,输出最小值。

n,q≤7.5×105n,q\leq7.5\times10^5n,q7.5×105

神仙题,不愧是IOI

首先有一个O(n2)O(n^2)O(n2)的 dp

f(l,r)=min⁡{f(l,k−1)+(r−k+1)hk,(k−l+1)hk+f(k+1,r)}f(l,r)=\min\{f(l,k-1)+(r-k+1)h_k,(k-l+1)h_k+f(k+1,r)\}f(l,r)=min{f(l,k1)+(rk+1)hk,(kl+1)hk+f(k+1,r)}

其中kkkl,rl,rl,r中的最大值的位置(如有多个随便选一个),即讨论钦定的点在最大值的左侧或右侧,然后另一侧的点贡献都是最大值

我觉得我考场上能想到这步就不错了

这个 dp 转移已经O(1)O(1)O(1)了,也不好压成一维,所以要么用可持久化之类的东西强行压状态,要么就不记录无用的状态

直接想的话两条路都不好走,但注意到这个过程实际上是最值分治,自然地想到笛卡尔树

哪里自然了啊kora

具体地讲,建出序列的笛卡尔树,然后在树上做上面dp,每个点只记录它代表的区间的dp值,这样就可以O(n)O(n)O(n)处理出来了。

然而就算处理出来了你仍然无法快速计算答案,因为询问区间可能会被拆成很多小段,你需要像平衡树一样沿着树递归下去。而笛卡尔树高是O(n)O(n)O(n)的,仍然可以被卡成狗。

不过思路感觉很对,考虑怎么优化

观察一下这个dp方程式

f(l,r)=min⁡{f(l,k−1)+(r−k+1)hk,f(k+1,r)+(k−l+1)hk}f(l,r)=\min\{f(l,k-1)+(r-k+1)h_k,f(k+1,r)+(k-l+1)h_k\}f(l,r)=min{f(l,k1)+(rk+1)hk,f(k+1,r)+(kl+1)hk}

套到树上:当前子树根结点是kkk,为了计算f(l,k−1)f(l,k-1)f(l,k1)f(k+1,r)f(k+1,r)f(k+1,r),我们需要继续往左右子树递归计算,我们这样子是不行的

但这个f(l,k−1)f(l,k-1)f(l,k1)f(k+1,r)f(k+1,r)f(k+1,r)比较特殊:它们都有一个端点是固定的!

为了叙述方便,下面只讨论f(k+1,r)f(k+1,r)f(k+1,r),左边的f(l,k−1)f(l,k-1)f(l,k1)是同理的

我们要是知道右子树的区间的所有前缀的dp信息就好了

看上去很扯,但实际上是可行的!

假设我们分别知道kkk的左右子树的前缀信息,也就是知道f(l,l...k−1)f(l,l...k-1)f(l,l...k1)f(k+1,k+1...r)f(k+1,k+1...r)f(k+1,k+1...r),现在考虑怎么合并f(l,l...r)f(l,l...r)f(l,l...r)

显然左边是不用管的

对于右边,我们再把这个方程式搬出来。为了看着顺眼,我把rrr换成了iii

f(l,i)=min⁡{f(l,k−1)+(i−k+1)hk,f(k+1,i)+(k−l+1)hk}f(l,i)=\min\{f(l,k-1)+(i-k+1)h_k,f(k+1,i)+(k-l+1)h_k\}f(l,i)=min{f(l,k1)+(ik+1)hk,f(k+1,i)+(kl+1)hk}

注意这个iii是在[k+1,r][k+1,r][k+1,r]内的,冷静分析一下,发现这个东西就是在原来的基础上整体加一个数,然后和一个一次函数取min⁡\minmin,因为是个区间,所以可以用线段树维护!

而这个方程是可以找到一个分界点,使得分界点左边取左边的值,右边取右边的值。原因是iii每增加111,左边的值固定增加hkh_khk,而右边增加f(k+1,i+1)−f(k+1,i)f(k+1,i+1)-f(k+1,i)f(k+1,i+1)f(k+1,i),区间往右扩张一位增加的代价总不可能大于区间最大值吧……所以左边迟早会超过右边,而且不会被反超。线段树上二分即可。

什么?线段树开不下?

但仔细想想会发现不同的位置是不会冲突的,即每个点xxx维护它当前处理的左端点到xxx的dp值,所以开一个线段树就可以了。

线段树合并应该也可以

f(l,k−1)f(l,k-1)f(l,k1)的话再开一棵线段树,左右倒过来就可以了

然后把询问离线,每组询问挂在区间最大值的点上面,建笛卡尔树的时候顺便处理一下就可以了。

复杂度O(nlog⁡n)O(n\log n)O(nlogn)

#include <iostream>
#include <cstring>
#include <cctype>
#include <cstdio>
#include <vector>
#define MAXN 750005
using namespace std;
inline int read()
{int ans=0;char c=getchar();while (!isdigit(c)) c=getchar();while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();return ans;
}
typedef long long ll;
int n;
struct SegmentTree
{#define lc p<<1#define rc p<<1|1struct node{int l,r,tag;ll k,b,lv,rv;}t[MAXN<<2];void build(int p,int l,int r){t[p].l=l,t[p].r=r;if (l==r) return;int mid=(l+r)>>1;build(lc,l,mid),build(rc,mid+1,r);}inline void pushcov(int p,ll k,ll b){t[p].k=k,t[p].b=b;t[p].lv=k*t[p].l+b,t[p].rv=k*t[p].r+b;t[p].tag=1;}inline void pushadd(int p,ll k,ll b){t[p].k+=k,t[p].b+=b;t[p].lv+=k*t[p].l+b,t[p].rv+=k*t[p].r+b;if (!t[p].tag) t[p].tag=2;		}inline void pushdown(int p){if (t[p].tag){if (t[p].tag==1) pushcov(lc,t[p].k,t[p].b),pushcov(rc,t[p].k,t[p].b);if (t[p].tag==2) pushadd(lc,t[p].k,t[p].b),pushadd(rc,t[p].k,t[p].b);t[p].tag=t[p].k=t[p].b=0;}}inline void update(int p){t[p].lv=t[lc].lv,t[p].rv=t[rc].rv;} ll query(int p,int k){if (t[p].l==t[p].r) return t[p].lv;pushdown(p);if (k<=t[lc].r) return query(lc,k);return query(rc,k);}void search(int p,int l,int r,ll k1,ll b1,ll b2){if (l<=t[p].l&&t[p].r<=r){if (k1*t[p].l+b1<=t[p].lv+b2&&k1*t[p].r+b1<=t[p].rv+b2) return pushcov(p,k1,b1);if (t[p].lv+b2<=k1*t[p].l+b1&&t[p].rv+b2<=k1*t[p].r+b1) return pushadd(p,0,b2);}if (r<t[p].l||t[p].r<l) return;pushdown(p);search(lc,l,r,k1,b1,b2),search(rc,l,r,k1,b1,b2);update(p);}
}lt,rt;
int h[MAXN];
inline int Max(const int& x,const int& y){return h[x]>h[y]? x:y;}
int st[20][MAXN],LOG[MAXN];
inline int rmq(int l,int r)
{int t=LOG[r-l+1];return Max(st[t][l],st[t][r-(1<<t)+1]);
}
int ql[MAXN],qr[MAXN];
ll ans[MAXN];
vector<int> lis[MAXN];
void solve(int l,int r)
{if (l>r) return;int k=rmq(l,r);solve(l,k-1),solve(k+1,r);for (int i=0;i<(int)lis[k].size();i++){int L=ql[lis[k][i]],R=qr[lis[k][i]];ans[lis[k][i]]=h[k]*(R-L+1ll);if (L<k) ans[lis[k][i]]=min(ans[lis[k][i]],rt.query(1,L)+(R-k+1ll)*h[k]);if (k<R) ans[lis[k][i]]=min(ans[lis[k][i]],(k-L+1ll)*h[k]+lt.query(1,R));}ll tl=rt.query(1,l),tr=lt.query(1,r);lt.search(1,k,r,h[k],tl+h[k]*(1ll-k),(k-l+1ll)*h[k]);rt.search(1,l,k,-h[k],tr+h[k]*(k+1ll),(r-k+1ll)*h[k]);
}
int main()
{n=read();int q=read();for (int i=1;i<=n;i++) h[i]=read();lt.build(1,1,n);rt.build(1,1,n);for (int i=1;i<=n;i++) st[0][i]=i;for (int j=1;j<20;j++)for (int i=1;i+(1<<(j-1))<=n;i++)st[j][i]=Max(st[j-1][i],st[j-1][i+(1<<(j-1))]);LOG[0]=-1;for (int i=1;i<=n;i++) LOG[i]=LOG[i>>1]+1;for (int i=1;i<=q;i++) ql[i]=read()+1,qr[i]=read()+1,lis[rmq(ql[i],qr[i])].push_back(i);solve(1,n);for (int i=1;i<=q;i++) printf("%lld\n",ans[i]);return 0;
}

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

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

相关文章

【半小时大话.net依赖注入】(一)理论基础+实战控制台程序实现AutoFac注入

第一章|理论基础实战控制台程序实现AutoFac注入第二章|AutoFac的常见使用套路第三章|实战Asp.Net Framework Web程序实现AutoFac注入第四章|实战Asp.Net Core自带DI实现依赖注入第五章|实战Asp.Net Core引入AutoFac的两种方式简介该系列共5篇文章&#xff0c;旨在以实战模式&am…

P4198 楼房重建 线段树 + 区间合并

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 题面有点问题&#xff0c;按照人类正常的理解来就好啦。 思路&#xff1a; 可以想到维护每个位置的一个斜率&#xff0c;模拟的话就是从第一个位置开始向后选&#xff0c;当某个位置斜率大于当前位置的时…

【IOI2018】狼人【Kruscal重构树】【主席树】

题意&#xff1a;nnn个点mmm条边的无向图&#xff0c;qqq次询问&#xff0c;每次给定s,t,L,Rs,t,L,Rs,t,L,R&#xff0c;判断是否存在一条sss到ttt的路径&#xff0c;使得路径上可以找到一点kkk,满足此路径s∼ks\sim ks∼k的部分标号都≥L\geq L≥L且k∼tk\sim tk∼t标号都≤R\…

基于 Docker Compose 实践 .NET Core 的现代化架构 2:在容器中集成 Skywalking APM

本章节代码已经上传至 https://github.com/siegrainwong/.NET-Core-with-Docker/tree/master/Part2系列大纲还是先介绍一下目录&#xff0c;这次我们讲第二篇&#xff1a;用 docker-compose 启动 WebApi 和 SQL Server在容器中集成 Skywalking APM通过 nginx-proxy 对 ES、Skyw…

【雅礼集训2017】字符串【后缀自动机】【数据分治】

题意&#xff1a;给定一个字符串SSS和mmm个区间[li,ri][l_i,r_i][li​,ri​],qqq次询问&#xff0c;每次给定长度为kkk的字符串www和区间[a,b][a,b][a,b]&#xff0c;求对于所有i∈[a,b]i\in[a,b]i∈[a,b]&#xff0c;www在[li,ri][l_i,r_i][li​,ri​]内的子串在SSS中出现次数…

AtCoder Regular Contest 100 E - Or Plus Max Sos dp

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一个长度为2n2^n2n的数组&#xff0c;让你对于所有的1≤k≤2n−11\le k\le 2^n-11≤k≤2n−1求最大的aiaj,0≤i<j≤2n−1,iorj≤ka_ia_j,0\le i<j\le2^n-1,i\ \ or \ \ j\le kai​aj​,0≤i<j≤…

使用Minikube部署本地Kubernetes集群(二十九)

前言 使用Minikube部署本地k8s集群相对比较简单&#xff0c;非常推荐将其用于本地k8s开发环境&#xff0c;唯一麻烦点的仅仅是网络问题。在本篇教程中&#xff0c;我们使用了国内的镜像来完成本地k8s集群的搭建。如果搭建过程中出现错误&#xff0c;建议使用mini…

Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2) F. Bits And Pieces sosdp预处理超集

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; n≤1e6,ai≤2e6n\le1e6,a_i\le2e6n≤1e6,ai​≤2e6 思路&#xff1a; 由于(aj&ak)(a_j \And a_k)(aj​&ak​)打的括号&#xff0c;所以应该放在一起考虑&#xff0c;现在我们可以枚举aia_iai​&…

【PKUWC2018】随机算法【状压dp】【组合计数】

题意&#xff1a;一张nnn个点mmm条边的无向无权图&#xff0c;求以下算法计算最大独立集的正确率&#xff1a;随机一个排列&#xff0c;依次考虑排列中每一个点&#xff0c;如果不与任何一个独立集中的点相邻则将其加入独立集。模998244353998244353998244353。 n≤20n\leq20n≤…

架构杂谈《一》

架构杂谈《一》从传统单体架构到服务化架构的发展历程典型的单体架构分为三个层级&#xff0c;Web层、业务逻辑层和数据存储层&#xff0c;每个层的指责分别如下&#xff1a;Web 层&#xff1a;负责与用户交互或者对外提供接口业务逻辑层&#xff1a;为了实现业务逻辑而设计的流…

hdu 3308 LCIS 线段树 + 区间合并

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 日常水一篇题解。 带修改的求区间连续的递增序列&#xff0c;我们考虑用线段树维护。 直接维护mlenmlenmlen是区间最长的递增序列&#xff0c;lslsls是从左端点开始的最长递增序列&#xf…

【ARC103D】Distance Sums【树论】【构造】

题意&#xff1a;一棵nnn个点的无权树&#xff0c;给定每个点iii到其他所有点的距离之和did_idi​&#xff0c;保证did_idi​两两不同。构造或判断无法构造一棵满足条件的树。 n≤105n\leq 10^5n≤105 首先对于非根结点uuu&#xff0c;有 dudfau−sizu(n−sizu)d_ud_{fa_u}-si…

从零开始实现ASP.NET Core MVC的插件式开发(二) - 如何创建项目模板

标题&#xff1a;从零开始实现ASP.NET Core MVC的插件式开发(二) - 如何创建项目模板作者&#xff1a;Lamond Lu地址&#xff1a;https://www.cnblogs.com/lwqlun/p/11155666.html源代码&#xff1a;https://github.com/lamondlu/DynamicPlugins在上一篇中&#xff0c;我们介绍…

Codeforces Round #112 (Div. 2) E. Compatible Numbers sosdp

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 以下假设all1<<22all1<<22all1<<22。 转化问题&#xff0c;对于每个aia_iai​我们都计算xaixorallxa_i\ \ xor \ \ allxai​ xor all&#xff0c;对于所有xxx的子集都…

【CF1349D】Slime and Biscuits【概率期望】【解方程】

题意&#xff1a;nnn个人共有mmm个饼干&#xff0c;每轮随机选一个饼干随机给一个另外的人&#xff0c;所有饼干都在一个人手里时游戏结束&#xff0c;求期望进行次数。模998244353998244353998244353。 n≤105,m≤3105n\leq10^5,m\leq3\times10^5n≤105,m≤3105 首先肯定是每…

多租户通用权限设计(基于 casbin)

所谓权限控制, 概念并不复杂, 就是确认某个操作是否能做, 本质上仅仅就是个bool判断.权限几乎是每个系统必不可少的功能, 和具体业务结合之后, 在系统中往往表现的非常复杂和难于控制, 很大部分原因是把权限和具体业务结合的太过紧密, 把业务的复杂度也加入到权限控制中来了.一…

Codeforces Round #225 (Div. 1) E. Vowels 容斥 + sosdp

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你nnn个长度为333的串&#xff0c;串的每个字母都在a−za-za−z范围内&#xff0c;定义一个串合法当且仅当这个串中含有至少一个元音字母。现在他忘记了元音字母都有那几个&#xff0c;显然有2242^{24}224…

【CF1344D】Résumé Review【数学】【二分】

题意&#xff1a;给定长度为nnn的自然数序列aaa和整数kkk&#xff0c;要求构造长度为nnn的自然数序列bbb&#xff0c;使得0≤bi≤ai,∑bik0\leq b_i\leq a_i,\sum b_ik0≤bi​≤ai​,∑bi​k&#xff0c;且∑bi(ai−bi2)\sum b_i(a_i-b_i^2)∑bi​(ai​−bi2​)最大化。 n≤105…

容器化单页面应用中RESTful API的访问

最近在工作中&#xff0c;需要让运行在容器中的单页面应用程序能够访问外部的RESTful API。这个需求看起来并不困难&#xff0c;不过实现起来还是有些曲折的。在此&#xff0c;我就将这部分内容总结一下。在入正题之前&#xff0c;有个一问题&#xff0c;就是为什么要将单页面应…

2020牛客暑期多校训练营(第六场)H.Harmony Pairs 数位dp

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一个nnn&#xff0c;问你有多少对0≤a≤b≤n0\le a\le b\le n0≤a≤b≤n满足S(a)>S(b)S(a)>S(b)S(a)>S(b)。其中S(a)S(a)S(a)表示aaa的十进制各位数之和。 思路&#xff1a; 显然的数位dpdpd…