1. 程式人生 > >李超樹詳解

李超樹詳解

ref query math sca www. size double 是個 main

李超樹是個什麽東西呢?

其實就是一棵線段樹。。。。

我們來看這一道題

其實就是這樣一道題目

在二維空間中插入一條直線,詢問x=k的地方最上面一條直線的編號

李超樹儲存的是區間[l,r]中‘最優線段‘,

最優線段,就是[l,r]中最暴露最長的線段

可以發現在k處的答案就是

所有包含此區間的最優線段中的最優解

代碼也好寫

# include<iostream>
# include<cstdio>
# include<algorithm>
# include<cstring>
# include<cmath>
using
namespace std; const int mn = 50005; int n,tot,tr[mn*4]; double b[100005],k[100005]; char s[200]; double f(int id,int x) { return k[id]*(x-1)+b[id]; } void update(int cur,int l,int r,int z) { if(l==r) { if(f(z,l) > f(tr[cur],l)) tr[cur]=z; return ; } int mid=l+r>>1
; if(k[tr[cur]] < k[z]) { if(f(z,mid) > f(tr[cur],mid)){ update(cur<<1,l,mid,tr[cur]); tr[cur]=z; } else update(cur<<1|1,mid+1,r,z); } if(k[tr[cur]] > k[z]) { if(f(z,mid) > f(tr[cur],mid)) { update(cur
<<1|1,mid+1,r,tr[cur]); tr[cur]=z; } else update(cur<<1,l,mid,z); } } double query(int cur,int l,int r,int x) { if(l==r) return f(tr[cur],x); int mid=l+r>>1; if(mid>=x) return max(f(tr[cur],x),query(cur<<1,l,mid,x)); else return max(f(tr[cur],x),query(cur<<1|1,mid+1,r,x)); } int main() { int x; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%s",s); if(s[0]==P) { ++tot; scanf("%lf%lf",&b[tot],&k[tot]); update(1,1,mn-10,tot); } else { scanf("%d",&x); printf("%d\n",int(query(1,1,mn-10,x)/100)); } } return 0; }

李超樹詳解