李超线段树用来在平面内动态插入线段,求\\(x=t\\)直线与这些线段交点的最值
核心是维护每个区间的“最优势线段”,即终点位置处最高的线段,询问室对所有包含\\(t\\)的区间的最优势线段计算答案,最后取\\(max\\)
模板题:JSOI2008BlueMary开公司
插入直线,求单点最大值
(看代码)
#include<bits/stdc++.h>
using namespace std;
const int N=50004;
#define lc (p<<1)
#define rc (p<<1|1)
int n=50000,Q;
char s[20];
double tk[N<<2],tb[N<<2];
bool tfl[N<<2];
void modify(int p,int l,int r,double k,double b){
if(!tfl[p]){tfl[p]=1;tk[p]=k;tb[p]=b;return;}
int mid=l+r>>1;
double l1=l*k+b,r1=r*k+b;
double l2=l*tk[p]+tb[p],r2=r*tk[p]+tb[p];
if(l1<=l2&&r1<=r2)return;
if(l1>l2&&r1>r2){tk[p]=k;tb[p]=b;return;}
double x=(b-tb[p])/(tk[p]-k);
if(l1>l2){
if(x>mid){
modify(rc,mid+1,r,tk[p],tb[p]);
tk[p]=k;tb[p]=b;
}
else modify(lc,l,mid,k,b);
}
else{
if(x>mid)modify(rc,mid+1,r,k,b);
else{
modify(lc,l,mid,tk[p],tb[p]);
tk[p]=k;tb[p]=b;
}
}
}
double query(int p,int l,int r,int x){
if(l==r)return tk[p]*x+tb[p];
int mid=l+r>>1;
double ret=tk[p]*x+tb[p];
if(x<=mid)return max(ret,query(lc,l,mid,x));
else return max(ret,query(rc,mid+1,r,x));
}
int main(){
scanf("%d",&Q);
while(Q--){
scanf("%s",s);
if(s[0]==\'P\'){
static double x,y;
scanf("%lf%lf",&x,&y);
modify(1,1,n,y,x-y);
}
else{
static int x;
scanf("%d",&x);
cout<<(long long)(query(1,1,n,x)/100)<<"\\n";
}
}
return (0-0);
}