线段树维护单调栈/单调递增序列
线段树维护单调栈/单调递增序列
线段树在维护区间时可以维护一个单调栈。
P4198 楼房重建
题意:维护全局最大上升序列大小。
更新
线段树当前节点存储整个区间的最大值,对于该题,左子树的区间答案可以直接继承,然后用左子树区间的最大值查询右子树的答案并记录在该节点上。
void update(const int &x,const double &k,const int &ro=1,const int &l=1,const int &r=n){
if(l==r) return ans[ro]=1,mx[ro]=k,void();
x<=mid?update(x,k,ls,l,mid):update(x,k,rs,mid+1,r);
mx[ro]=max(mx[ls],mx[rs]);
ans[ro]=ans[ls]+query(mx[ls],rs,mid+1,r);
}
其中,查询右区间比传的值大的节点个数的查询方式如下:
int query(const double &k,const int &ro=1,const int &l=1,const int &r=n){
if(mx[ro]<=k) return 0;
if(l==r) return mx[ro]>k;
if(mx[ls]<=k) return query(k,rs,mid+1,r);
else return query(k,ls,l,mid)+ans[ro]-ans[ls];
}
P4425 转盘
维护后缀答案最小值。比较值为原序列,答案维护最小值。
void update(const int &x,const int &ro=1,const int &l=1,const int &r=n){
if(l==r) return mx[ro]=a[x],void();
x<=mid?update(x,ls,l,mid):update(x,rs,mid+1,r);
mx[ro]=max(mx[ls],mx[rs]);
mn[ro]=query(mx[rs],ls,l,mid);
}
int query(const int &k,const int &ro=1,const int &l=1,const int &r=n){
if(l==r) return mx[ro]>k?k+l:INF;
return k<mx[rs]?min(mn[ro],query(k,rs,mid+1,r)):query(k,ls,l,mid);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现