题目大意:
给出若干条线段,用 (x1,y2),(x2,y2) 表示其两端点坐标,现在要求支持两种操作:
0 x1 y1 x2 y2
表示加入一条新的线段 (x1,y2),(x2,y2)1 x0
询问所有线段中,x坐标在 x0 处的最高点的 y 坐标是什么,如果对应位置没有线段,则输出
思路:
使用李超树维护
每一个加入的线段 在它能覆盖的线段树区间中修改
修改的时候判断它是否在中点的位置更优
然后将这个区间原来维护的线段与新线段比较
不优的那个考虑下放到左右儿子区间中继续更新
查询的时候答案为经过的所有线段树的线段中最大的
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #include<map> 10 #define inf 2139062143 11 #define ll long long 12 #define MAXN 100100 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 18 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 int n,m,mx[MAXN<<2]; 22 struct seg{double k,b;}tag[MAXN<<2]; 23 inline void build(int k,int l,int r) 24 { 25 tag[k].k=0,tag[k].b=-inf; 26 if(l==r) return ; 27 int mid=(l+r)>>1; 28 build(k<<1,l,mid);build(k<<1|1,mid+1,r); 29 } 30 inline void real_mdf(int k,int l,int r,seg x) 31 { 32 //cout<<k<<" "<<l<<" "<<r<<" "<<x.k<<" "<<x.b<<endl; 33 if(l==r) {if(tag[k].k*l+tag[k].b<x.k*l+x.b) tag[k]=x;return ;} 34 int mid=(l+r)>>1; 35 if(tag[k].k*mid+tag[k].b<x.k*mid+x.b) swap(tag[k],x); 36 //cout<<"i: "<<k<<" "<<l<<" "<<r<<" "<<x.k<<" "<<x.b<<endl; 37 if(tag[k].k*l+tag[k].b<x.k*l+x.b) real_mdf(k<<1,l,mid,x); 38 if(tag[k].k*r+tag[k].b<x.k*r+x.b) real_mdf(k<<1|1,mid+1,r,x); 39 } 40 inline void mdf(int k,int l,int r,int a,int b,seg x) 41 { 42 if(a>b) return ; 43 //cout<<k<<" "<<l<<" "<<r<<" "<<a<<" "<<b<<" "<<x.k<<" "<<x.b<<endl; 44 if(l==a&&r==b) {real_mdf(k,l,r,x);return ;} 45 int mid=(l+r)>>1; 46 if(b<=mid) mdf(k<<1,l,mid,a,b,x); 47 else if(a>mid) mdf(k<<1|1,mid+1,r,a,b,x); 48 else {mdf(k<<1,l,mid,a,mid,x);mdf(k<<1|1,mid+1,r,mid+1,b,x);} 49 } 50 inline double query(int k,int l,int r,int x) 51 { 52 //cout<<x<<" "<<tag[k].k*x+tag[k].b<<endl; 53 if(l==r) return tag[k].k*x+tag[k].b; 54 int mid=(l+r)>>1;double res; 55 //cout<<k<<" "<<res<<endl; 56 if(x<=mid) res=query(k<<1,l,mid,x); 57 else res=query(k<<1|1,mid+1,r,x); 58 return max(tag[k].k*x+tag[k].b,res); 59 } 60 int main() 61 { 62 //freopen("C2.in","r",stdin); 63 n=read(),m=read();int a,b,x,y,z;double k,B; 64 build(1,1,MAXN-100); 65 for(int i=1;i<=n;i++) 66 { 67 x=read(),y=read(),a=read(),b=read(); 68 //cout<<6<<endl; 69 if(x==a) k=0,B=max(y,b); 70 else k=(double)(y-b)/(x-a),B=y-k*x; 71 //cout<<k<<" "<<b<<endl; 72 mdf(1,1,MAXN-100,max(1,min(a,x)),min(MAXN-100,max(x,a)),(seg){k,B}); 73 } 74 while(m--) 75 { 76 z=read(); 77 if(z) {a=read(),k=query(1,1,MAXN-100,a);printf("%.3lf\n",k<=-inf?0:k);} 78 else 79 { 80 x=read(),y=read(),a=read(),b=read(); 81 //cout<<6<<endl; 82 if(x==a) k=0,B=max(y,b); 83 else k=(double)(y-b)/(x-a),B=y-k*x; 84 //cout<<k<<" "<<b<<endl; 85 mdf(1,1,MAXN-100,max(1,min(a,x)),min(MAXN-100,max(x,a)),(seg){k,B}); 86 } 87 //system("pause"); 88 } 89 }