3165: [Heoi2013]Segment 线段树 标记永久化
2018-04-01 19:56
405 查看
Description
要求在平面直角坐标系下维护两个操作:
1.在平面上加入一条线段。记第i条被插入的线段的标号为i。
2.给定一个数k,询问与直线 x = k相交的线段中,交点最靠上的线段的编号。
实现起来还是比较简单的,注意相同时输出编号较小的线段。
要求在平面直角坐标系下维护两个操作:
1.在平面上加入一条线段。记第i条被插入的线段的标号为i。
2.给定一个数k,询问与直线 x = k相交的线段中,交点最靠上的线段的编号。
题解:
实现起来还是比较简单的,注意相同时输出编号较小的线段。
代码:
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; const int Maxn=100010,Maxk=40000; const double eps=1e-7; struct line { bool flag; int x0,y0,x1,y1; double k,b; line(int _x0=0,int _y0=0,int _x1=0,int _y1=0) { x0=_x0,y0=_y0,x1=_x1,y1=_y1; if(abs(x0-x1)>eps)k=(double)(y0-y1)/(x0-x1),flag=true; else flag=false; b=(double)y0-k*x0; } }L[Maxn];int llen=0; double get(int x,int p) { if(L[p].flag)return (double)x*L[p].k+L[p].b; else return max(L[p].y0,L[p].y1); } struct Seg{int l,r,lc,rc,tag;bool empty;}tr[Maxk<<1]; int tot=0; void build(int l,int r) { int t=++tot; tr[t].l=l;tr[t].r=r;tr[t].tag=-1;tr[t].empty=true; if(l==r)return; int mid=l+r>>1; tr[t].lc=tot+1,build(l,mid); tr[t].rc=tot+1,build(mid+1,r); } int query(int x,int p) { if(tr[x].empty)return 0; if(tr[x].l==tr[x].r)return tr[x].tag; int mid=tr[x].l+tr[x].r>>1,lc=tr[x].lc,rc=tr[x].rc,re=tr[x].tag,t; if(p<=mid)t=query(lc,p); else t=query(rc,p); if(re==-1)re=t; else { if(t>0&&get(p,t)>get(p,re))re=t; else if(t>0&&abs(get(p,t)-get(p,re))<=eps&&t<re)re=t; } if(re==-1)re=0; return re; } void work(int x,int l,int r,int p) { if(tr[x].tag==-1) { tr[x].tag=p; tr[x].empty=false; return; } int mid=tr[x].l+tr[x].r>>1,lc=tr[x].lc,rc=tr[x].rc; if(get(l,p)<=get(l,tr[x].tag)&&get(r,p)<=get(r,tr[x].tag))return; if(get(l,p)>=get(l,tr[x].tag)&&get(r,p)>=get(r,tr[x].tag)&& (abs(get(l,p)-get(l,tr[x].tag))>eps&&abs(get(r,p)-get(r,tr[x].tag))>eps)){tr[x].tag=p;return;} if(l==r)return; int t=tr[x].tag; double Y1=get(l,p),Y2=get(r,p),Y3=get(l,t),Y4=get(r,t); double X=(L[p].b-L[t].b)/(L[t].k-L[p].k); if(X<=mid) { if(Y1>Y3) { tr[x].tag=t; work(lc,l,mid,p); } else { tr[x].tag=p; work(lc,l,mid,t); } } else { if(Y1>Y3) { tr[x].tag=p; work(rc,mid+1,r,t); } else { tr[x].tag=t; work(rc,mid+1,r,p); } } } void insert(int x,int l,int r,int p) { int mid=tr[x].l+tr[x].r>>1,lc=tr[x].lc,rc=tr[x].rc; if(tr[x].l==l&&tr[x].r==r) { work(x,l,r,p); return; } if(r<=mid)insert(lc,l,r,p); else if(l>mid)insert(rc,l,r,p); else insert(lc,l,mid,p),insert(rc,mid+1,r,p); tr[x].empty=(tr[lc].empty&tr[rc].empty); } int n; int main() { build(1,Maxk); int ans=0; scanf("%d",&n); while(n--) { int op,k; scanf("%d",&op); if(!op) { scanf("%d",&k); int x=((k+ans-1)%39989+1); ans=query(1,x); printf("%d\n",ans); } else { int x0,y0,x1,y1; scanf("%d%d%d%d",&x0,&y0,&x1,&y1); x0=(x0+ans-1)%39989+1,y0=(y0+ans-1)%1000000000+1; x1=(x1+ans-1)%39989+1,y1=(y1+ans-1)%1000000000+1; if(x0>x1)swap(x0,x1),swap(y0,y1); L[++llen]=line(x0,y0,x1,y1); insert(1,x0,x1,llen); } } }
相关文章推荐
- BZOJ 3165: [Heoi2013]Segment 标记永久化
- BZOJ 3165 Heoi2013 Segment 线段树
- bzoj 3165: [Heoi2013]Segment 线段树
- 【bzoj3165】【HEOI2013】【Segment】【线段树】
- BZOJ_3165_[Heoi2013]Segment_线段树
- 【BZOJ 3165】 [Heoi2013]Segment 李超线段树
- [李超线段树] BZOJ3165 [Heoi2013]. Segment
- [bzoj3165][Heoi2013]Segment——李超线段树
- [线段树] BZOJ 3165: [Heoi2013]Segment
- 【李超线段树】BZOJ3165 [Heoi2013]Segment
- [李超线段树] BZOJ 3165: [Heoi2013]Segment
- 【bzoj3165】[Heoi2013]Segment 神奇的线段树
- 3165: [Heoi2013]Segment
- 【BZOJ 3165】【HEOI 2013】Segment
- 李超线段树 [Heoi2013]Segment
- BZOJ3165 [Heoi2013]Segment
- 【BZOJ-3165】Segment 李超线段树(标记永久化)
- 【李超线段树】BZOJ3165(Heoi2013)[Segment]题解
- BZOJ3165: [Heoi2013]Segment
- BZOJ3165 : [Heoi2013]Segment