對於初學李超樹的我簡直是噩夢,它比以前的模板題(上一篇博客)噁心在全部線段再也不覆蓋全區間。
咱們要分狀況討論了:
對於被插入線段包含的區間,咱們仍像以前同樣操做;
部分包含的,像普通線段樹同樣分割插入線段的區間就好了,並不要修改。c++
if(p<=mid) update(l,mid,p,q,id,lc); if(q>mid) update(mid+1,r,p,q,id,rc);
總代碼:spa
#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=4e4,mod1=39989,mod2=1e9; int n,t1,t2,t3,t4,tag[M<<2],num=0,opt,last_ans=0; struct xd{double s,p;}line[N]; 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 p,int q,int id,int x){ int mid=l+r>>1; if(p<=l&&r<=q){ if(l==r){if(f(id,l)>f(tag[x],l)) tag[x]=id; return;} if(line[tag[x]].p>line[id].p){ if(f(tag[x],mid)<f(id,mid)) update(mid+1,r,mid+1,r,tag[x],rc),tag[x]=id; else update(l,mid,l,mid,id,lc); } else{ if(f(tag[x],mid)<f(id,mid)) update(l,mid,l,mid,tag[x],lc),tag[x]=id; else update(mid+1,r,mid+1,r,id,rc); } return; } if(p<=mid) update(l,mid,p,q,id,lc); if(q>mid) update(mid+1,r,p,q,id,rc); } int query(int l,int r,int p,int x){ if(l==r) return tag[x]; int mid=l+r>>1,t; double ans=f(tag[x],p); if(p<=mid){t=query(l,mid,p,lc); return ans>f(t,p)?tag[x]:t;} t=query(mid+1,r,p,rc); return ans>f(t,p)?tag[x]:t; } int main(){ n=read(); for(int i=1;i<=n;++i){ opt=read(); if(!opt) t1=read(),t1=(t1+last_ans-1)%mod1+1,last_ans=query(1,M,t1,1),printf("%d\n",last_ans); else{ t1=read(),t3=read(),t2=read(),t4=read(),t1=(t1+last_ans-1)%mod1+1,t2=(t2+last_ans-1)%mod1+1,t3=(t3+last_ans-1)%mod2+1,t4=(t4+last_ans-1)%mod2+1; if(t1>t2) swap(t1,t2),swap(t3,t4); ++num,line[num].p=(t1==t2)?0:(t4-t3)*1.00000000/(t2-t1),line[num].s=max(t4-t2*line[num].p,t3-t1*line[num].p),update(1,M,t1,t2,num,1); } } return 0; }