您的位置:首页 > 其它

BZOJ3165 & 洛谷4097:[HEOI2013]Segment——题解

2018-06-12 14:37 316 查看

https://www.lydsy.com/JudgeOnline/problem.php?id=3165

https://www.luogu.org/problemnew/show/P4097

要求在平面直角坐标系下维护两个操作:
1.在平面上加入一条线段。记第i条被插入的线段的标号为i。
2.给定一个数k,询问与直线 x = k相交的线段中,交点最靠上的线段的编号。 

李超线段树板子题,参考代码:https://zepto.blog.luogu.org/solution-p4097

李超线段树参考:https://www.geek-share.com/detail/2712249497.html

参考代码还是很清新的。

#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef double dl;
const int N=40010;
inline int read(){
int X=0,w=0;char ch=0;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
return w?-X:X;
}
struct node{
int l,r,id;
dl yl,yr;
node(int x1=0,int y1=0,int x2=0,int y2=0,int i=0){
l=x1,r=x2;yl=y1,yr=y2;id=i;
if(l==r)yl=yr=max(yl,yr);
}
dl k(){return (yr-yl)/(r-l);}
dl point(int x){return l==r?yl:yl+k()*(x-l);}
void lm(int x){yl=point(x),l=x;}
void rm(int x){yr=point(x),r=x;}
}tr[N*4];
int lastans,n;
node maxn(node a,node b,int k){
dl y1=a.point(k),y2=b.point(k);
if(y1==y2)return a.id<b.id?a:b;
return y1>y2?a:b;
}
node query(int a,int l,int r,int k){
if(l==r)return tr[a];
int mid=(l+r)>>1;node ans;
if(k<=mid)ans=query(a<<1,l,mid,k);
else ans=query(a<<1|1,mid+1,r,k);
return maxn(ans,tr[a],k);
}
void upt(int a,int l,int r,node k){
if(k.l<l)k.lm(l);
if(r<k.r)k.rm(r);
int mid=(l+r)>>1;
if(maxn(k,tr[a],mid).id==k.id)swap(k,tr[a]);
if(min(tr[a].yl,tr[a].yr)>=max(k.yl,k.yr))return;
if(l==r)return;
if(tr[a].k()>k.k())upt(a<<1,l,mid,k);
else upt(a<<1|1,mid+1,r,k);
}
void insert(int a,int l,int r,node k){
if(r<k.l||k.r<l)return;
if(k.l<l)k.lm(l);
if(r<k.r)k.rm(r);
if(k.l==l&&r==k.r){
upt(a,l,r,k);
return;
}
if(l==r)return;
int mid=(l+r)>>1;
insert(a<<1,l,mid,k);insert(a<<1|1,mid+1,r,k);
}
inline int num(int p){
return (read()+lastans-1)%p+1;
}
int main(){
n=read();int id=0;
while(n--){
int op=read();
if(op==0){
int k=num(39989);
printf("%d\n",lastans=query(1,1,39989,k).id);
}else{
int x0=num(39989),y0=num(1e9);
int x1=num(39989),y1=num(1e9);
if(x0>x1)swap(x0,x1),swap(y0,y1);
node k=node(x0,y0,x1,y1,++id);
insert(1,1,39989,k);
}
}
return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: