李超樹模板題啦,全部線段覆蓋全區間,並且仍是單點查詢,太良心了。
什麼?你不會李超樹,看看個人這篇博客吧
原本不想寫註釋的,但爲了本身之後能看懂,仍是打一打吧。
\(line[x]:\)存的是第\(x\)條線段的斜率和截距,\(tag[x]:\)存的是線段樹上點\(x\)的優點線段是哪一條。html
#include<bits/stdc++.h> #define re register #define lc x<<1 #define rc x<<1|1 using namespace std; const int N=1e5+6,M=5e5; int n,t,tag[M<<2],num=0; struct xd{double s,p;}line[N]; char c[12]; inline int read(){ int T=0,F=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();} while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar(); return F*T; } double f(int id,int x){return line[id].p*x+line[id].s;} void update(int l,int r,int id,int x){ if(l==r){if(f(id,l)>f(tag[x],l)) tag[x]=id; return;} int mid=l+r>>1; if(line[tag[x]].p>line[id].p){ if(f(tag[x],mid)<f(id,mid)) update(mid+1,r,tag[x],rc),tag[x]=id; else update(l,mid,id,lc); } else{ if(f(tag[x],mid)<f(id,mid)) update(l,mid,tag[x],lc),tag[x]=id; else update(mid+1,r,id,rc); } } double query(int l,int r,int p,int x){ if(l==r) return f(tag[x],l); int mid=l+r>>1; double ans=f(tag[x],p); if(p<=mid) return max(ans,query(l,mid,p,lc)); return max(ans,query(mid+1,r,p,rc)); } int main(){ n=read(); for(int i=1;i<=n;++i){ scanf("%s",c); if(c[0]=='Q') t=read(),printf("%d\n",(int)(query(1,M,t,1)/100.0)); else ++num,scanf("%lf%lf",&line[num].s,&line[num].p),line[num].s-=line[num].p,update(1,M,num,1); } return 0; }