Li Chaoshu-slanted line segment tree

Introduction

Li Chaoshu is used to solve a problem: insert a number of straight lines (or line segments) into the plane, and query the maximum value of the intersection coordinate y of the line segment intersecting with the straight line x=a,

Regardless of this kind of problem, it seems to be quite individual. Many flat problems or DP (slope optimization) problems can be converted into this kind of problem. However, when encountering this kind of problem, Li Chaoshu is much better than balanced tree.

thought

The Li Chaoshu code looks very similar to an ordinary line segment tree. The difference is that each node maintains not [l,r]an interval, but a line segment with a slope with the x coordinates of l and r at both ends:

(Note that the relationship between the height of the line segment of each layer is uncertain, so the drawing is just for good-looking)

In this way, the query only needs to be checked like a line segment tree.

Then how to insert the line segment? (The straight line is the line segment from -inf to inf) Just insert it like a line segment tree. When the line segment overlaps with the interval, there are three situations as follows:

  1. The new line segment can be directly covered above the old line segment
  2. The new line segment can be ignored directly below the old line segment
  3. The new and old line segments intersect , and any one of the line segments is separated and inserted into the two sons, and then the node retains the other line segment. The complexity of doing this is actually equivalent to separating the two line segments. One side must intersect and the other side is disjoint. The disjoint cases are 1, 2, and O(1) is judged. Then it is passed down. A log.

The worst is the complexity of inserting a line segment O(log^2n)(inserting a straight line is O (logn)true, because it only corresponds to one interval), the query is O (logn), the total complexity is O (nlogn)~ O (nlog ^ 2n).

board

The code looks like this (linear dynamic opening version):

#define INF 0x7f7f7f7f
#define ll long long
int IN;
struct lcs{
	int ls,rs;ll k,b;lcs(){}
	lcs(ll K,ll B){ls=rs=0,k=K,b=B;}
}t[MAXN<<4];
inline void add(int x,ll l,ll r,ll k,ll b){//插入一条y=kx+b的直线
	if(x==0)return;
	ll tk=t[x].k,tb=t[x].b,mid=(l+r)>>1;
	if(l*k+b>=l*tk+tb&&r*k+b>=r*tk+tb){
		t[x].k=k,t[x].b=b;return;
	}
	else if(l*k+b<l*tk+tb&&r*k+b<r*tk+tb)return;
	else{
		if(!t[x].ls)t[x].ls=++IN,t[IN]=lcs(tk,tb);
		else add(t[x].ls,l,mid,tk,tb);
		if(!t[x].rs)t[x].rs=++IN,t[IN]=lcs(tk,tb);
		else add(t[x].rs,mid+1,r,tk,tb);
		t[x].k=k,t[x].b=b;
	}
}
inline ll sch(int x,ll l,ll r,ll g){//查找x=g处的最高点
	if(x==0)return -INF;
	ll mid=(l+r)>>1,res=g*t[x].k+t[x].b;
	if(g<=mid)res=max(res,sch(t[x].ls,l,mid,g));
	else res=max(res,sch(t[x].rs,mid+1,r,g));
	return res;
}

 

Guess you like

Origin blog.csdn.net/weixin_43960287/article/details/110469918