【NOI2017模拟4.2】查询
来源:互联网 发布:python 抽象类 编辑:程序博客网 时间:2024/06/06 13:20
题目
Description
给出若干条线段,用(x1,y1),(x2,y2)表示其两端点坐标,现在要求支持两种操作:
0 x1 y1 x2 y2
表示加入一条新的线段,(x1,y1)-(x2,y2)
1 x0
询问所有线段中,x坐标在x0处的最高点的y坐标是什么,如果对应位置没有线段,则输出0。
Input
第一行两个正整数N,M为初始的线段个数和操作个数
接下来N行,每行四个整数,表示一条线段
接下来M行,每行为一个操作”0 x1 y1 x2 y2”或”1 x0”
Output
对于每一个询问操作,输出一行,为一个实数,当你的答案与标准答案误差不超过1e-2是,则视为正确。
Sample Input
3 4
0 -1 4 1
4 2 7 2
7 1 8 2
1 4
1 3
0 3 3 6 3
1 3
Sample Output
2.000000
0.500000
3.000000
Data Constraint
对于10%的数据:n,m<=1000
另外20%的数据:所有的1操作都在0操作之后
另外20%的数据:所有线段的两端的x坐标都包含所有的询问的x坐标,你可以将每条线段当做直线处理
对于100%的数据:n<=50000,m<=150000,x1,x2,y1,y2,x0均为整数,0
题解
考虑用一颗树来存储当前的信息,可以用类似线段树的方法,每一个节点储存的是一条线段,而这条线段满足:前面出现过的所有线段在这一段区间内不会出现一半以上都比这条线段y位置要高的情况,那么在查找的时候我们就把经过的线段树中每一条线段在这个位置的最值比较出来就可以了
现在考虑的是如何维护这棵树,在每次新插入一条线段时,我们先把树的横纵坐标调到和这个线段匹配(线段也可能会超过询问的范围,那么就缩小它),然后与线段树里的节点比较一下,不足一半的继续往下递归就可以了
贴代码
const maxn=100000; tcc=-9999999;var tree:array[0..800005,1..2]of extended; bz:array[0..800005]of boolean; i,j,l,m,n,x,y,z:longint; x1,y1,x2,y2,t1:longint; k,b,ans:extended;function max(x,y:longint):longint;begin if x>y then exit(x) else exit(y);end;function min(x,y:longint):longint;begin if x<y then exit(x) else exit(y);end;procedure change(v,l,r,x,y:longint;k,b:extended);var mid:longint; p,t1,t2,t3,t4:extended;begin if (l=x) and (r=y) then begin if (l=r) and (bz[v]=true) then begin if k*l+b>tree[v,1]*l+tree[v,2] then begin tree[v,1]:=k; tree[v,2]:=b; end; exit; end; mid:=(l+r) div 2; p:=tree[v,1]*mid+tree[v,2]; if bz[v]=false then begin tree[v,1]:=k; tree[v,2]:=b; bz[v]:=true; if l=r then exit; change(v*2,l,mid,l,mid,k,b); change(v*2+1,mid+1,r,mid+1,r,k,b); end else begin if k*mid+b>p then begin t1:=tree[v,1]; tree[v,1]:=k; k:=t1; t1:=tree[v,2]; tree[v,2]:=b; b:=t1; end; p:=tree[v,1]*mid+tree[v,2]; t1:=k*l+b; t2:=tree[v,1]*l+tree[v,2]; t3:=k*mid+b; if ((t1<=t2) and (t3>p)) or ((t1>t2) and (t3<=p)) then change(v*2,l,mid,l,mid,k,b) else begin t1:=k*r+b; t2:=tree[v,1]*r+tree[v,2]; t3:=k*mid+b; t4:=tree[v,1]*mid+tree[v,2]; if ((t1>t2) and (t3<=t4)) or ((t1<=t2) and (t3>t4)) then change(v*2+1,mid+1,r,mid+1,r,k,b); end; end; end else begin mid:=(l+r) div 2; if (y<=mid) then change(v*2,l,mid,x,y,k,b) else if (x>mid) then change(v*2+1,mid+1,r,x,y,k,b) else begin change(v*2,l,mid,x,mid,k,b); change(v*2+1,mid+1,r,mid+1,y,k,b); end; end;end;procedure get(v,l,r,x:longint);var mid:longint;begin if (x*tree[v,1]+tree[v,2]>ans) and (bz[v]=true) then ans:=x*tree[v,1]+tree[v,2]; if l=r then begin if abs(ans-tcc)<0.000001 then ans:=0; if abs(ans)<0.0000001 then writeln('0.0000000') else writeln(ans:0:6) end else begin mid:=(l+r) div 2; if x<=mid then get(v*2,l,mid,x) else get(v*2+1,mid+1,r,x); end;end;begin assign(input,'query.in'); reset(input); assign(output,'query.out'); rewrite(output); readln(n,m); for i:=1 to n do begin readln(x1,y1,x2,y2); if x1>x2 then begin t1:=x1; x1:=x2; x2:=t1; t1:=y1; y1:=y2; y2:=t1; end; if x1=x2 then begin k:=0; b:=max(y1,y2); if (x1<=0) or (x1>=maxn) then continue; change(1,1,maxn,x1,x1,k,b); continue; end; k:=(y2-y1)/(x2-x1); b:=y1-k*x1; if x1>maxn then continue; if x2<=0 then continue; change(1,1,maxn,max(x1,1),min(x2,maxn),k,b); end; for i:=1 to m do begin read(l); if l=1 then begin readln(l); ans:=tcc; get(1,1,maxn,l); end else begin readln(x1,y1,x2,y2); if x1>x2 then begin t1:=x1; x1:=x2; x2:=t1; t1:=y1; y1:=y2; y2:=t1; end; if x1=x2 then begin if (x1<=0) or (x1>maxn) then continue; k:=0; b:=max(y1,y2); change(1,1,maxn,x1,x1,k,b); continue; end; k:=(y2-y1)/(x2-x1); b:=y1-k*x1; if x1>maxn then continue; if x2<=0 then continue; change(1,1,maxn,max(x1,1),min(x2,maxn),k,b); end; end; close(input); close(output);end.
- 【NOI2017模拟4.2】查询
- 【JZOJ5039】【NOI2017模拟4.2】查询
- 【NOI2017模拟4.2】查询【线段树】
- 【NOI2017模拟4.2】押韵
- jzoj 5039. 【NOI2017模拟4.2】查询 线段树
- 【JZOJ5040】【NOI2017模拟4.2】押韵
- NOI2017模拟3.1 总结
- NOI2017模拟3.8 总结
- 【NOI2017模拟3.30】原谅
- 【NOI2017模拟6.26】A
- 【NOI2017模拟6.29】呵呵
- 【NOI2017模拟6.2】字符串
- jzoj 5040. 【NOI2017模拟4.2】押韵 trie树+树形dp
- 【JZOJ5037】【NOI2017模拟3.30】轮回
- [JZOJ100003]【NOI2017模拟.4.1】 Tree
- 【JZOJ5036】【NOI2017模拟3.30】原谅
- 【JZOJ5037】【NOI2017模拟3.30】轮回
- 【JZOJ100003】【NOI2017模拟.4.1】 Tree
- 精灵派项目中的Makefile 生成.a和.so
- JAVA 序列化
- LeetCode专题----Design
- Spring整合redis
- ModBus协议传输模式
- 【NOI2017模拟4.2】查询
- JSP学习总结
- CSS 精华一页纸
- mysql
- Dagger2 最基础入门——一个刚刚跳坑的汉子
- C# 中的委托和事件(详解)
- VS2013/MFC基于对话框编程:[11]编辑框
- 用DOM解析XML文件并存入mysql数据库
- Android JNI和NDK学习(04)--NDK调试方法