LOJ #6034. 「雅礼集训 2017 Day2」线段游戏(李超线段树)

题目
主席树套李超树。
一开始以为空间是 O ( n log 2 n ) O(n\log^2n) 的。
然后发现这个神奇的数据结构(李超树)是 O ( n ) O(n) 空间的。。。。
注意不要往李超树里面加斜率不存在的线段,好像处理不了的样子,在外面简单维护即可。
时间复杂度 O ( n log 2 n ) O(n\log ^2n)
A C   C o d e \mathrm {AC \ Code}

#include<bits/stdc++.h>
#define maxn 100005
#define maxp 8000006
#define rep(i,j,k) for(int i=(j);i<=k;i++)
#define TC 1,1,100000
#define db double 
#define Ct const 
using namespace std;

int n,m;
int rt[maxn<<2],mxh[maxn],hdp[maxn];

char cb[1<<15],*cs=cb,*ct=cb;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
void read(int &res){
	char ch;bool f=0;
	for(;!isdigit(ch=getc());) if(ch=='-') f=1;
	for(res=ch-'0';isdigit(ch=getc());res=res*10+ch-'0');
	(f) && (res=-res);
}
struct Line{
	int x[2],y[2];
	db caly(db a)Ct{ return (a - x[0]) * (y[1] - y[0]) / (x[1] - x[0]) + y[0]; } 
}tr[maxp];
int tot,lc[maxp],rc[maxp];

void ins(int &u,int l,int r,Ct Line &A){
	if(!u) return (void)(tr[u=++tot]=A);
	int mid=(l+r)>>1;
	if(A.caly(mid) > tr[u].caly(mid)){
		if(l^r){
			if(1ll*(A.x[1]-A.x[0])*(tr[u].y[1]-tr[u].y[0])-1ll*(A.y[1]-A.y[0])*(tr[u].x[1]-tr[u].x[0]) > 0)
				ins(rc[u],mid+1,r,tr[u]);
			else
			 	ins(lc[u],l,mid,tr[u]);
		}
		tr[u] = A;
	}
	else{
		if(l^r){
			if(1ll*(A.x[1]-A.x[0])*(tr[u].y[1]-tr[u].y[0])-1ll*(A.y[1]-A.y[0])*(tr[u].x[1]-tr[u].x[0]) < 0)
				ins(rc[u],mid+1,r,A);
			else
			 	ins(lc[u],l,mid,A);
		}
	}
}
void ins(int u,int l,int r,int ql,int qr,Ct Line &A){
	if(l>qr || ql>r) return;
	if(ql<=l&&r<=qr) return (void)(ins(rt[u],1,100000,A));
	int mid=(l+r)>>1;
	ins(u<<1,l,mid,ql,qr,A),ins(u<<1|1,mid+1,r,ql,qr,A);
}
db ans;
void qry2(int u,int l,int r,int p){
	if(!u) return;
	ans = max(ans , tr[u].caly(p));
	int mid=(l+r)>>1;
	if(p<=mid) qry2(lc[u],l,mid,p);
	else qry2(rc[u],mid+1,r,p);
}
void qry(int u,int l,int r,int p){
	qry2(rt[u],1,100000,p);
	if(l==r) return;
	int mid=(l+r)>>1;
	if(p<=mid) qry(u<<1,l,mid,p);
	else qry(u<<1|1,mid+1,r,p);
}
int main(){
	read(n),read(m);
	rep(i,1,n){
		Line A;
		read(A.x[0]),read(A.y[0]),read(A.x[1]),read(A.y[1]);
		if(A.x[0] > A.x[1]) swap(A.x[0],A.x[1]),swap(A.y[0],A.y[1]);
		if(A.x[0] == A.x[1]){
			if(A.x[0] > 0 && A.x[0] <= 100000){
				if(!hdp[A.x[0]]) mxh[A.x[0]] = max(A.y[0],A.y[1]);
				mxh[A.x[0]] = max(mxh[A.x[0]],max(A.y[0],A.y[1])) , hdp[A.x[0]] = 1;
			}
		}
		else ins(TC,max(A.x[0],1),min(A.x[1],100000),A);
	}
	rep(i,1,m){
		int op;read(op);
		if(op == 0){
			Line A;
			read(A.x[0]),read(A.y[0]),read(A.x[1]),read(A.y[1]);
			if(A.x[0] > A.x[1]) swap(A.x[0],A.x[1]),swap(A.y[0],A.y[1]);
			if(A.x[0] == A.x[1]){
				if(A.x[0] > 0 && A.x[0] <= 100000){
					if(!hdp[A.x[0]]) mxh[A.x[0]] = max(A.y[0],A.y[1]);
					mxh[A.x[0]] = max(mxh[A.x[0]],max(A.y[0],A.y[1])),hdp[A.x[0]]=1;
				}
			}
			else ins(TC,max(A.x[0],1),min(A.x[1],100000),A);
		}
		else{
			int x0;read(x0);
			ans = -(1e18);
			qry(TC,x0);
			if(hdp[x0]) ans = max(ans , 1.0*mxh[x0]);
			if(ans == -1e18) ans = 0;
			printf("%.3lf\n",ans);
		}
	}
}
发布了627 篇原创文章 · 获赞 91 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/qq_35950004/article/details/103721653