李超线段树

根据函数的单调性与函数间的交点,维护/求若干条线段/直线在某个位置的最值,可用于优化斜率优化dp

模板题 求若干条线段在某个横坐标上的最大值,区间修改单点查询动态开点版

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10,rm=39989;
typedef double db;
typedef pair<double,int> pdi;
const db eps=1e-9;
int n,opt,lans,cnt;
struct node{
	db k,b;
	int x0,y0,x1,y1;
	inline db calc(db x){
		return k*x+b;
	}
}p[maxn];
int t[maxn<<4],lc[maxn<<4],rc[maxn<<4],tot,root;
bool cmp(int i,int j,int x){
	double ansi=p[i].calc(x),ansj=p[j].calc(x);
	if(ansi-ansj>eps) return 1;
	if(ansj-ansi>eps) return 0;
	return i<j;
}
inline void upd(int &u,int l,int r,int k){ 
	if(!u) u=++tot;
	int mid=(l+r)>>1;
	if(!t[u]){
		t[u]=k;
		return;
	}
	if(cmp(k,t[u],mid)) swap(k,t[u]);
	if(l==r) return;
	if(cmp(k,t[u],l)) upd(lc[u],l,mid,k);
	if(cmp(k,t[u],r)) upd(rc[u],mid+1,r,k);
}
inline void update(int &u,int ql,int qr,int l,int r,int k){
	if(!u) u=++tot;
	if(ql==l&&qr==r){
		upd(u,ql,qr,k);
		return;
	}
	int mid=(l+r)>>1;
	if(ql<=mid) update(lc[u],ql,min(qr,mid),l,mid,k);
	if(qr>mid) update(rc[u],max(ql,mid+1),qr,mid+1,r,k);
}
inline int qry(int u,int l,int r,int k){
	if(!u) return 0;
	if(l==r) return t[u];
	int mid=(l+r)>>1,ans=t[u],son;
	if(k<=mid){
		son=qry(lc[u],l,mid,k);
		if(cmp(son,ans,k)) ans=son;
	}
	else{
		son=qry(rc[u],mid+1,r,k);
		if(cmp(son,ans,k)) ans=son;
	}
	return ans;
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n;
	p[0].k=0,p[0].b=-2e9;
	for(int i=1;i<=n;i++){
		cin>>opt;
		if(opt){
			++cnt;
			cin>>p[cnt].x0>>p[cnt].y0>>p[cnt].x1>>p[cnt].y1;
			p[cnt].x0=(p[cnt].x0+lans-1)%39989+1,p[cnt].y0=(p[cnt].y0+lans-1)%1000000000+1;
			p[cnt].x1=(p[cnt].x1+lans-1)%39989+1,p[cnt].y1=(p[cnt].y1+lans-1)%1000000000+1;
			if(p[cnt].x0>p[cnt].x1) swap(p[cnt].x0,p[cnt].x1),swap(p[cnt].y0,p[cnt].y1);
			if(p[cnt].x1==p[cnt].x0){
				p[cnt].k=0,p[cnt].b=max(p[cnt].y0,p[cnt].y1);
				update(root,p[cnt].x1,p[cnt].x1,1,rm,cnt);
			}
			else{
				p[cnt].k=1.0*(p[cnt].y0-p[cnt].y1)/(p[cnt].x0-p[cnt].x1);
				p[cnt].b=p[cnt].y0-p[cnt].x0*p[cnt].k;
				update(root,p[cnt].x0,p[cnt].x1,1,rm,cnt);
			}
		}
		else{
			int x;
			cin>>x;
			x=(x+lans-1)%39989+1;
			lans=qry(root,1,rm,x);
			cout<<lans<<'\n';
		}
	}
	return 0;
}

CF932F Escape Through Leaf 动态开点+线段树合并

#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int lm=-1e5,rm=1e5,maxn=1e5+10;
typedef long long ll;
const ll inf=1e18;
int n,va[maxn],vb[maxn];
int tot,to[maxn<<1],nxt[maxn<<1],h[maxn];
inline void adde(int x,int y){
	to[++tot]=y;
	nxt[tot]=h[x];
	h[x]=tot;
}
int sum,t[maxn<<5],lc[maxn<<5],rc[maxn<<5],root[maxn<<5],cnt;
ll k[maxn],b[maxn];
inline ll calc(int i,ll x){
	return k[i]*x+b[i];
}
inline bool cmp(int i,int j,int x){
	ll y1=calc(i,x),y2=calc(j,x);
	return y1<y2;
}
inline void upd(int &u,int l,int r,int k){
	if(!u) u=++sum;
	if(!t[u]){
		t[u]=k;
		return;
	}
	if(l==r){
		if(cmp(k,t[u],l)) t[u]=k;
		return;
	}
	int mid=(l+r)>>1;
	if(cmp(k,t[u],mid)) swap(k,t[u]);
	if(cmp(k,t[u],l)) upd(lc[u],l,mid,k);
	if(cmp(k,t[u],r)) upd(rc[u],mid+1,r,k);
}
inline ll qry(int u,int l,int r,int k){
	if(!u) return inf;
	if(l==r) return calc(t[u],k);
	int mid=(l+r)>>1;
	ll ans=calc(t[u],k);
	if(k<=mid) ans=min(ans,qry(lc[u],l,mid,k));
	else ans=min(ans,qry(rc[u],mid+1,r,k));
	return ans;
}
inline int combine(int ua,int ub,int l,int r){
	if(!ua||!ub) return ua+ub;
	if(l==r){
		if(cmp(t[ub],t[ua],l)) return ub;
		return ua;
	}
	int mid=(l+r)>>1;
	lc[ua]=combine(lc[ua],lc[ub],l,mid);
	rc[ua]=combine(rc[ua],rc[ub],mid+1,r);
	upd(ua,l,r,t[ub]);
	return ua;
}
ll ans[maxn];
inline void dd(int x,int f){
	bool du=0;
	for(int i=h[x];i;i=nxt[i]){
		int y=to[i];
		if(y==f) continue;
		du=1;
		dd(y,x);
		root[x]=combine(root[x],root[y],lm,rm); 
	}
	if(du) ans[x]=qry(root[x],lm,rm,va[x]);
	k[++cnt]=vb[x];
	b[cnt]=ans[x];
	upd(root[x],lm,rm,cnt);
}
signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	k[0]=0;
	b[0]=inf;
	cin>>n;
	for(int i=1;i<=n;i++) cin>>va[i];
	for(int i=1;i<=n;i++) cin>>vb[i];
	for(int i=1,u,v;i<n;i++) cin>>u>>v,adde(u,v),adde(v,u);
	dd(1,0);
	for(int i=1;i<=n;i++) cout<<ans[i]<<' ';
	return 0;
}
posted @ 2025-08-25 10:54  _dlwlrma  阅读(31)  评论(5)    收藏  举报