标签:logs ble 坐标 upd 递归 线段树 博客 怎么 color
李超线段树:动态维护一个平面直角坐标系,支持在中间插入一条线段(或直线),询问与x=x0这条直线相交的所有线段中,交点的y坐标的最大(小)值。
线段树上每个区间维护在mid处y坐标最大的线段。(要标记永久化)
考虑怎么插入一条直线,假设它当前处理到了某个区间:(摘自yyb的博客https://www.cnblogs.com/cjyyb/p/10560973.html)
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=100005; int n,i; bool v[N*5]; double x,y,K[N*5],B[N*5]; char ch[20]; void update(int o,int l,int r,double k,double b) { if(!v[o]) {v[o]=true,K[o]=k,B[o]=b;return;} if(l==r) { if(k*l+b>K[o]*l+B[o]) K[o]=k,B[o]=b; return; } int mid=l+r>>1; double l1=k*l+b,r1=k*r+b,l2=K[o]*l+B[o],r2=K[o]*r+B[o]; if(l1>=l2&&r1>=r2) {K[o]=k,B[o]=b;return;} if(l1<=l2&&r1<=r2) return; double x=(b-B[o])/(K[o]-k); if(l1>=l2) { if(x>mid) {update(o<<1|1,mid+1,r,K[o],B[o]);K[o]=k,B[o]=b;} else update(o<<1,l,mid,k,b); } else { if(x>mid) update(o<<1|1,mid+1,r,k,b); else {update(o<<1,l,mid,K[o],B[o]);K[o]=k,B[o]=b;} } } double query(int o,int l,int r,int x) { if(l==r) return K[o]*l+B[o]; int mid=l+r>>1; double rtn=(v[o]?K[o]*x+B[o]:0.0); if(x<=mid) return max(rtn,query(o<<1,l,mid,x)); else return max(rtn,query(o<<1|1,mid+1,r,x)); } int main() { freopen("company.in","r",stdin); freopen("company.out","w",stdout); scanf("%d",&n); while(n--) { scanf("%s",ch); if(ch[0]==‘P‘) { scanf("%lf%lf",&x,&y); update(1,1,50000,y,x-y); } else { scanf("%d",&i); printf("%d\n",max(0,(int)query(1,1,50000,i)/100)); } } return 0; }
标签:logs ble 坐标 upd 递归 线段树 博客 怎么 color
原文地址:https://www.cnblogs.com/pthws/p/11079795.html