[JZOJ5039]查询
来源:互联网 发布:微信大屏幕霸屏源码 编辑:程序博客网 时间:2024/06/06 01:39
题目大意
给出平面上的
你要支持以下两个操作(总共
题目分析
既然所有坐标都在整点上,而且询问的
做模拟赛的时候我想到的一个特别逗的想法是:将所有线段下放到线段树上对应的区间,然后在线段树的每一个节点上用平衡树来维护凸壳。时空复杂度都是
其实在这题我们没有必要一个节点维护多条线段。考虑使用如下的算法:
先将线段下方到对应的区间上,如果这个区间的节点没有线段,我们就放上去。否则我们就比较一下当前线段和节点上的线段,在上端部分最长的线段储存在这个区间的节点上,短的那一条则递归到其在上面的那一边的子树里面,然后做类似的操作。如果下传到了叶子节点,则直接比较更新即可。
一条线段会下放到
代码实现
#include <algorithm>#include <iostream>#include <cfloat>#include <cctype>#include <cstdio>using namespace std;typedef long double db;int read(){ int x=0,f=1; char ch=getchar(); while (!isdigit(ch)) f=ch=='-'?-1:f,ch=getchar(); while (isdigit(ch)) x=x*10+ch-'0',ch=getchar(); return x*f;}const db INF=DBL_MAX;const int X=100000;struct P{ db x,y; P (db x_=0.,db y_=0.){x=x_,y=y_;} void load(){x=read(),y=read();} inline P operator+(P const p)const{return P(x+p.x,y+p.y);} inline P operator-(P const p)const{return P(x-p.x,y-p.y);} inline P operator*(db const k)const{return P(x*k,y*k);}};struct L{ P p,v; L (){} L (P p_,P v_){p=p_,v=v_;}};inline P ict(L l,db x0){return l.p+(l.v*((x0-l.p.x)/l.v.x));}struct segment_tree{ bool used[X+5<<3]; L seg[X+5<<3]; void modify(int x,int st,int en,int l,int r,L sg) { if (st>en) return; int mid=l+r>>1; if (st==l&&en==r) { if (!used[x]) used[x]=1,seg[x]=sg; else { db midx=(l+r)/2.; if (ict(seg[x],midx).y<ict(sg,midx).y) swap(sg,seg[x]); if (ict(seg[x],l).y<ict(sg,l).y) modify(x<<1,l,mid,l,mid,sg); if (ict(seg[x],r).y<ict(sg,r).y) modify(x<<1|1,mid+1,r,mid+1,r,sg); } return; } if (en<=mid) modify(x<<1,st,en,l,mid,sg); else if (mid+1<=st) modify(x<<1|1,st,en,mid+1,r,sg); else modify(x<<1,st,mid,l,mid,sg),modify(x<<1|1,mid+1,en,mid+1,r,sg); } db query(int x,int y,int l,int r) { db ret=used[x]?ict(seg[x],y).y:-INF; if (l==r) return ret; int mid=l+r>>1; if (y<=mid) return max(ret,query(x<<1,y,l,mid)); else return max(ret,query(x<<1|1,y,mid+1,r)); }}t;db val[X+5];int n,q;db ans;int main(){ freopen("query.in","r",stdin),freopen("query.out","w",stdout); n=read(),q=read(); for (int i=1;i<=X;++i) val[i]=-INF; for (int i=1;i<=n;++i) { P u,v; u.load(),v.load(); if (u.x==v.x) val[(int)u.x]=max(val[(int)u.x],max(u.y,v.y)); else { int l=max(1,min((int)u.x,(int)v.x)),r=min(X,max((int)u.x,(int)v.x)); t.modify(1,l,r,1,X,L(u,v-u)); } } for (P u,v;q--;) { int tp=read(),x; if (tp) x=read(),ans=max(val[x],t.query(1,x,1,X)),ans>=-1e+6?printf("%.6lf\n",(double)ans):printf("0\n"); else { P u,v; u.load(),v.load(); if (u.x==v.x) val[(int)u.x]=max(val[(int)u.x],max(u.y,v.y)); else { int l=max(1,min((int)u.x,(int)v.x)),r=min(X,max((int)u.x,(int)v.x)); t.modify(1,l,r,1,X,L(u,v-u)); } } } fclose(stdin),fclose(stdout); return 0;}
0 0
- [JZOJ5039]查询
- 【JZOJ5039】【NOI2017模拟4.2】查询
- 查询
- 查询
- 查询
- 查询
- 查询
- 查询
- 查询
- 查询
- 查询
- 查询
- 查询
- 查询
- 查询
- 查询
- 查询
- 查询
- studio开发文件被锁报错解决
- 详解 Android 的 Activity 组件
- 一个简单的android便签app
- 【Unity Shader】Shadow Caster、RenderType和_CameraDepthTexture
- 蓝桥杯模拟赛第五场
- [JZOJ5039]查询
- 使用链表实现栈(C语言)
- Android学习教程(二)之Activity启动模式
- 计算各种图形的周长
- poj_2299 归并排序找逆序数
- 算法训练 寻找数组中最大值
- JZOJ1489.2017.04.02【NOIP 普及组】模拟赛C组 T1区间
- hihocoder 1295 : 数论二·Eular质数筛法
- hdu5066——Harry And Physical Teacher(物理)