链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3165
题意:动态增加线段,求出横坐标纵坐标最高的被覆盖点所在线段。
这个题要用到李超线段树(orz李超)……大概这是李超那篇论文出现后第二年的题?不管了直接介绍这一数据结构。李超线段树的目的就是查询出每个点被线段覆盖的情况,操作无非就是插入线段和查询两件事。
插入线段:首先计算出原有线段和现在线段在这个区间之内的函数值,如果新线段一直大直接修改返回,如果一直小也直接返回,否则递归修改至单点或全部返回为止。
查询线段:不断地递归查询,从根节点整条数轴一直查询到单点,期间找到最值就进行修改。
可以证明,单次修改时间复杂度$O(log^2n)$,单次查询时间复杂度$O(logn)$,因此复杂度完全足够。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<map> 6 using namespace std; 7 const int maxn=100005,maxp=40005;const double eps=1e-9; 8 struct node 9 { 10 double k,b;int id;bool vis; 11 }S[maxn<<2]; 12 int dcmp(double x) 13 { 14 return (x>eps)-(x<-eps); 15 } 16 #define mid ((l+r)>>1) 17 #define lc root<<1 18 #define rc root<<1|1 19 #define lson lc,l,mid 20 #define rson rc,mid+1,r 21 inline void solve(int root,int l,int r,int idx,double k,double b) 22 { 23 if(!S[root].vis) 24 { 25 S[root].k=k,S[root].b=b,S[root].id=idx,S[root].vis=1; 26 return; 27 } 28 double y0=S[root].k*l+S[root].b,y1=k*l+b,y2=S[root].k*r+S[root].b,y3=k*r+b; 29 if(dcmp(y1-y0)>0&&dcmp(y3-y2)>0) 30 { 31 if(dcmp(k-S[root].k)==0&&dcmp(b-S[root].b)==0)return; 32 S[root].k=k,S[root].b=b,S[root].id=idx; 33 return; 34 } 35 if(dcmp(y1-y0)<=0&&dcmp(y3-y2)<=0)return; 36 solve(lson,idx,k,b);solve(rson,idx,k,b); 37 } 38 inline void insert(int root,int l,int r,int L,int R,int idx,double k,double b) 39 { 40 if(L<=l&&r<=R){solve(root,l,r,idx,k,b);return;} 41 if(L<=mid)insert(lson,L,R,idx,k,b);if(R>mid)insert(rson,L,R,idx,k,b); 42 } 43 inline void insert(int x0,int x1,int y0,int y1,int num) 44 { 45 int L=x0,R=x1;double k=1.0*(y1-y0)/(1.0*(x1-x0)),b=y0-x0*k;int idx=num;insert(1,1,maxp,L,R,idx,k,b); 46 } 47 double ans;int ans_id; 48 inline void query(int root,int l,int r,int pos) 49 { 50 double x=S[root].k*pos+S[root].b; 51 if(dcmp(x-ans)>0||dcmp(x-ans)==0&&S[root].id<ans_id)ans=x,ans_id=S[root].id; 52 if(l==r)return; 53 if(pos<=mid)query(lson,pos);else query(rson,pos); 54 } 55 int a[maxn],id[maxn]; 56 int haha() 57 { 58 int n;scanf("%d",&n);int lastans=0; 59 int opt,x0,y0,x1,y1,x,num=0; 60 while(n--) 61 { 62 scanf("%d",&opt); 63 if(!opt) 64 { 65 scanf("%d",&x),x=((x+lastans-1)%39989+1); 66 ans=ans_id=0;query(1,1,maxp,x); 67 if(ans<a[x]||ans==a[x]&&id[x]<ans_id)ans_id=id[x]; 68 printf("%d ",lastans=ans_id); 69 } 70 else 71 { 72 num++;scanf("%d%d%d%d",&x0,&y0,&x1,&y1); 73 x0=(x0+lastans-1)%39989+1,y0=(y0+lastans-1)%(int)1e9+1,x1=(x1+lastans-1)%39989+1,y1=(y1+lastans-1)%(int)1e9+1; 74 if(x0>x1)swap(x0,x1),swap(y0,y1); 75 if(x0==x1) 76 { 77 if(max(y0,y1)>a[x0])a[x0]=max(y0,y1),id[x0]=num; 78 } 79 else insert(x0,x1,y0,y1,num); 80 } 81 } 82 } 83 int sb=haha(); 84 int main(){;}