Typesetting math: 100%

斜率优化(李超树)

不会单调队列,又看到古神拿李超树切斜率优化特别顺手,遂来学了一下,确实挺好用。

李超树

一种用来快速维护有关线段的信息的数据结构,一般是 O(nlog2n) 的,在斜率优化题中用到的操作是 O(nlogn) 的(没有斜率优化题会卡 O(nlogn) 吧)。
原理是递归来判断线段在一段区间内的优劣,这个在做题时不用理会。只需要记住板子,然后把斜截式方程代到里面,按具体题目微调一下,然后就可以了。OIer只需要求出 dp 方程,转化成斜截式,代到李超树里就行了,可是李超树要考虑的事情就比较多了。

拿一道P5785 任务安排的代码当例子,按这个模板写就行。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ls t[now].l
#define rs t[now].r
const ll N=3*114514,M=1919810,inf=1145141919810;
ll n,s,ti[N],f[N],dp[N],id[N];
ll rt,cnt;
struct xx{
	ll val,id;
}a[N];
bool cmp(xx x,xx y){
	return x.val<y.val;
}
struct tree{
	ll k,b;
	ll l,r;
}t[4*N];
ll get(ll id,ll x){
	return t[id].k*x+t[id].b;
}
void pushdown(ll &now,ll l,ll r,ll k,ll b){
	if(!now) now=++cnt; //这里不一定
	ll mid=(l+r)>>1;
	ll la=get(now,a[l].val),ra=get(now,a[r].val);
	ll lx=k*a[l].val+b,rx=k*a[r].val+b;
	ll mid1=get(now,a[mid].val),mid2=k*a[mid].val+b;
	if(la<=lx&&ra<=rx) return;
	if(la>lx&&ra>rx){
		t[now].k=k,t[now].b=b;
		return;
	}
	if(mid1>mid2){
		swap(la,lx),swap(ra,rx);
		swap(t[now].k,k),swap(t[now].b,b);
	}
	if(la>lx) pushdown(ls,l,mid,k,b);
	if(ra>rx) pushdown(rs,mid+1,r,k,b);
}
ll query(ll now,ll l,ll r,ll tar){
	if(!now) return inf;
	ll mid=(l+r)>>1,ans=get(now,a[tar].val);
	if(tar<=mid) ans=min(ans,query(ls,l,mid,tar));
	else ans=min(ans,query(rs,mid+1,r,tar));
	return ans;
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin>>n>>s;
	for(int i=1;i<=n;++i){
		cin>>ti[i]>>f[i];
		ti[i]+=ti[i-1],f[i]+=f[i-1];
		a[i].val=ti[i]+s,a[i].id=i;
	}
	sort(a+1,a+n+1,cmp);
	for(int i=1;i<=n;++i) id[a[i].id]=i;
	for(int i=1;i<=n;++i){
		dp[i]=query(rt,1,n,id[i])+f[n]*s+ti[i]*f[i];
		pushdown(rt,1,n,-f[i],dp[i]);
	}
	cout<<dp[n];
	return 0;
}

斜率优化

题一般都是能很简单求出 O(n2) 的转移式,但是复杂度要求在 O(nlogn) 以内的,这个时候可以考虑斜率优化。因为使用的是李超树,所以斜截式就要列成 y=kx+b 的形式。一般来说,只与 i 相关的项放到 y,至于 j 相关的项和常数项放在 b,同时和 i,j 相关的放在 kx。然后有些题会有些特殊操作,需要微调。

posted @   和蜀玩  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· Trae初体验

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示