标签:-- using eset scanf ons 复杂 复杂度 http out
https://www.luogu.org/problemnew/show/P4097
李超线段树模板题。
插入一条线段,用log(n)的复杂度将它分配到不同区间内,对于每个区间,又要用log(n)的复杂度判断在所有子区间的优劣程度。
所以,插入复杂度是log^2(n)的,查询复杂度依然为log(n)。
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int N=100005,md1=39989,md2=1000000000; struct node { int l,r; double k,b; }p[N]; int n,i,len,ans,X0,Y0,X1,Y1,w[N*5],g[N]; double e; void update(int o,int l,int r,int id) { int mid=l+r>>1; if(l>=p[id].l&&r<=p[id].r) { if(!w[o]) {w[o]=id;return;} double l1=p[id].k*l+p[id].b,r1=p[id].k*r+p[id].b; double l2=p[w[o]].k*l+p[w[o]].b,r2=p[w[o]].k*r+p[w[o]].b; if(l1>l2&&r1>r2) {w[o]=id;return;} if(l1<=l2&&r1<=r2) return; double x=(p[id].b-p[w[o]].b)/(p[w[o]].k-p[id].k); if(l1>=l2) { if(x>mid) {update(o<<1|1,mid+1,r,w[o]);w[o]=id;} else update(o<<1,l,mid,id); } else { if(x<=mid) {update(o<<1,l,mid,w[o]);w[o]=id;} else update(o<<1|1,mid+1,r,id); } return; } if(p[id].l<=mid) update(o<<1,l,mid,id); if(p[id].r>mid) update(o<<1|1,mid+1,r,id); } void query(int o,int l,int r,int x) { if(w[o]) { if(p[w[o]].k*x+p[w[o]].b>e||(p[w[o]].k*x+p[w[o]].b==e&&w[o]<ans)) ans=w[o],e=p[w[o]].k*x+p[w[o]].b; } if(l==r) return; int mid=l+r>>1; if(x<=mid) query(o<<1,l,mid,x); else query(o<<1|1,mid+1,r,x); } int main() { freopen("segment.in","r",stdin); freopen("segment.out","w",stdout); scanf("%d",&n); while(n--) { scanf("%d",&i); if(i==1) { ++len; scanf("%d%d%d%d",&X0,&Y0,&X1,&Y1); X0=(X0+ans-1)%md1+1,Y0=(Y0+ans-1)%md2+1; X1=(X1+ans-1)%md1+1,Y1=(Y1+ans-1)%md2+1; if(X0>X1) swap(X0,X1),swap(Y0,Y1); if(X0!=X1) { p[len]=(node){X0,X1,1.0*(Y1-Y0)/(X1-X0),Y0-1.0*(Y1-Y0)/(X1-X0)*X0}; update(1,1,md1,len); } else { p[len].r=Y1; if(Y1>p[g[X0]].r) g[X0]=len; } } else { scanf("%d",&X0); X0=(X0+ans-1)%md1+1; ans=g[X0];e=p[g[X0]].r; query(1,1,md1,X0); printf("%d\n",ans); } } return 0; }
标签:-- using eset scanf ons 复杂 复杂度 http out
原文地址:https://www.cnblogs.com/pthws/p/11080152.html