BZOJ3165[Heoi2013]Segment——李超线段树
题目描述
要求在平面直角坐标系下维护两个操作:
1.在平面上加入一条线段。记第i条被插入的线段的标号为i。
2.给定一个数k,询问与直线 x = k相交的线段中,交点最靠上的线段的编号。
输入
第一行一个整数n,表示共n 个操作。
接下来n行,每行第一个数为0或1。
若该数为 0,则后面跟着一个正整数 k,表示询问与直线
x = ((k +lastans–1)%39989+1)相交的线段中交点(包括在端点相交的情形)最靠上的线段的编号,其中%表示取余。若某条线段为直线的一部分,则视作直线与线段交于该线段y坐标最大处。若有多条线段符合要求,输出编号最小的线段的编号。
若该数为 1,则后面跟着四个正整数 x0, y0, x 1, y 1,表示插入一条两个端点为
((x0+lastans-1)%39989+1,(y0+lastans-1)%10^9+1)和((x
1+lastans-1)%39989+1,(y1+lastans-1)%10^9+1) 的线段。
其中lastans为上一次询问的答案。初始时lastans=0。
输出
对于每个 0操作,输出一行,包含一个正整数,表示交点最靠上的线段的编号。若不存在与直线相交的线段,答案为0。
样例输入
1 8 5 10 8
1 6 7 2 6
0 2
0 9
1 4 7 6 7
0 5
样例输出
0 3
提示
对于100%的数据,1 ≤ n ≤ 10^5 , 1 ≤ k, x0, x1 ≤ 39989, 1 ≤ y0 ≤ y1 ≤ 10^9。
模板题,线段树上每个点存覆盖整个区间的最优线段。对于每条输入线段如果完全覆盖当前区间就进行以下判断,否则看它在左右子区间是否有覆盖的部分递归下去。对于完全覆盖当前区间分四种情况讨论:
1、当前区间无线段覆盖,直接将新线段存起来
2、当前区间存的线段完全覆盖新线段,直接返回
3、新线段完全覆盖当前区间存的线段,将新线段存起来
4、当前区间存的线段和新线段相交,将区间中点处更高的存为当前区间的线段,并将另一条线段向它左右两端较高的那端的子区间递归下去
查询时只要将查询路径上所有线段取最高的那个即可。
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define eps 1e-8
using namespace std;
int num[200010];
double k[100010];
double b[100010];
int n;
int opt;
int cnt;
int ans;
int X0,Y0,X1,Y1;
bool cmp(double x)
{
return fabs(x)<=eps;
}
double f(int id,int x)
{
return k[id]*x+b[id];
}
bool judge(int idx,int idy,int x)
{
double fx=f(idx,x);
double fy=f(idy,x);
return cmp(fx-fy)?idx<idy:fx<fy;
}
void change(int rt,int l,int r,int L,int R,int id)
{
int mid=(l+r)>>1;
if(L<=l&&r<=R)
{
if(judge(id,num[rt],l)&&judge(id,num[rt],r))
{
return ;
}
if(judge(num[rt],id,l)&&judge(num[rt],id,r))
{
num[rt]=id;
return ;
}
if(judge(num[rt],id,mid))
{
swap(num[rt],id);
}
if(judge(num[rt],id,l))
{
change(rt<<1,l,mid,L,R,id);
}
else
{
change(rt<<1|1,mid+1,r,L,R,id);
}
return ;
}
if(L<=mid)
{
change(rt<<1,l,mid,L,R,id);
}
if(R>mid)
{
change(rt<<1|1,mid+1,r,L,R,id);
}
}
int query(int rt,int l,int r,int x)
{
if(l==r)
{
return num[rt];
}
int mid=(l+r)>>1;
int res=x<=mid?query(rt<<1,l,mid,x):query(rt<<1|1,mid+1,r,x);
if(judge(res,num[rt],x))
{
res=num[rt];
}
return res;
}
int main()
{
ans=-1;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&opt);
if(opt)
{
scanf("%d%d%d%d",&X0,&Y0,&X1,&Y1);
cnt++;
X0=(X0+ans+39989)%39989+1,Y0=(1ll*Y0+ans+1000000000)%1000000000+1;
X1=(X1+ans+39989)%39989+1,Y1=(1ll*Y1+ans+1000000000)%1000000000+1;
if(X1<X0)
{
swap(X1,X0);
swap(Y1,Y0);
}
if(X1==X0)
{
k[cnt]=0;
b[cnt]=max(Y0,Y1);
}
else
{
k[cnt]=(double)(Y1-Y0)/(X1-X0);
b[cnt]=Y1-k[cnt]*X1;
}
change(1,1,40000,X0,X1,cnt);
}
else
{
scanf("%d",&X0);
X0=(X0+ans+39989)%39989+1;
ans=query(1,1,40000,X0);
printf("%d\n",ans);
ans--;
}
}
}
BZOJ3165[Heoi2013]Segment——李超线段树的更多相关文章
- BZOJ3165: [Heoi2013]Segment(李超线段树)
题意 题目链接 Sol 李超线段树板子题.具体原理就不讲了. 一开始自己yy着写差点写自闭都快把叉积搬出来了... 后来看了下litble的写法才发现原来可以写的这么清晰简洁Orz #include& ...
- 【BZOJ-3165】Segment 李超线段树(标记永久化)
3165: [Heoi2013]Segment Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 368 Solved: 148[Submit][Sta ...
- Luogu P4097 [HEOI2013]Segment 李超线段树
题目链接 \(Click\) \(Here\) 李超线段树的模板.但是因为我实在太\(Naive\)了,想象不到实现方法. 看代码就能懂的东西,放在这里用于复习. #include <bits/ ...
- 2019.02.11 bzoj3165: [Heoi2013]Segment(线段树)
传送门 题意简述:要求支持两种操作: 插入一条线段. 询问与直线x=kx=kx=k相交的线段中,交点最靠上的线段的编号. 思路: 直接上李超线段树即可. 代码: #include<bits/st ...
- 【BZOJ 3165】 [Heoi2013]Segment 李超线段树
所谓李超线段树就是解决此题一类的问题(线段覆盖查询点最大(小)),把原本计算几何的题目变成了简单的线段树,巧妙地结合了线段树的标记永久化与标记下传,在不考虑精度误差的影响下,打法应该是这样的. #in ...
- P4097 [HEOI2013]Segment 李超线段树
$ \color{#0066ff}{ 题目描述 }$ 要求在平面直角坐标系下维护两个操作: 在平面上加入一条线段.记第 i 条被插入的线段的标号为 i 给定一个数 k,询问与直线 x = k 相交的线 ...
- BZOJ.3165.[HEOI2013]Segment(李超线段树)
BZOJ 洛谷 对于线段,依旧是存斜率即可. 表示精度误差一点都不需要管啊/托腮 就我一个人看成了mod(10^9+1)吗.. //4248kb 892ms #include <cstdio&g ...
- Segment 李超线段树
题目大意: 要求在平面直角坐标系下维护两个操作: 1.在平面上加入一条线段.记第 i 条被插入的线段的标号为 i 2.给定一个数 k,询问与直线 x = k 相交的线段中,交点最靠上的线段的编号. 若 ...
- 【洛谷P4097】Segment 李超线段树
题目大意:维护一个二维平面,给定若干条线段,支持询问任意整数横坐标处对应的纵坐标最靠上的线段的 id,相同高度取 id 值较小的,强制在线. 题解:初步学习了李超线段树.李超线段树的核心思想在于通过标 ...
随机推荐
- PowerMock单元测试踩坑与总结
1.Mock是什么? 通过提供定制的类加载器以及一些字节码篡改技巧的应用,PowerMock 现了对静态方法.构造方法.私有方法以及 Final 方法的模拟支持,对静态初始化过程的移除等强大的功能. ...
- 领域驱动设计(DDD:Domain-Driven Design) 介绍
Eric Evans的“Domain-Driven Design领域驱动设计”简称DDD,Evans DDD是一套综合软件系统分析和设计的面向对象建模方法,本站Jdon.com是国内公开最早讨论DDD ...
- flask请求流程详解
先看一个流程图: 1.当一个请求进入的时候,Flask框架首先会实例化一个Request Context,封装了请求信息,保存在Request中.生成请求上下文后,Flask框架会将请求上下文推入到_ ...
- rest_framework之视图及源码剖析
最初形态(工作中可能会使用) 引子 Django的CBV我们应该都有所了解及使用,大体概括一下就是通过定义类并在类中定义get post put delete等对应于请求方法的方法,当请求来的时候会自 ...
- hdu 2063 给男女匹配 (匈牙利算法)
来源:http://acm.hdu.edu.cn/showproblem.php?pid=2063 题意: 有k个组合a,b组合,代表a愿意与b坐过山车,共m个女生 n个男生,问有多少个满意的匹配 题 ...
- R语言绘制QQ图
无论是直方图还是经验分布图,要从比较上鉴别样本是否处近似于某种类型的分布是困难的 QQ图可以帮我们鉴别样本的分布是否近似于某种类型的分布 R语言,代码如下: > qqnorm(w);qqline ...
- 《梦断代码》Scott Rosenberg著(二)
书中有一段说的是一个闪烁缺陷——在改变某软件中某个窗体的尺寸时,屏幕会闪烁一秒钟左右.虽然该缺陷不会影响程序运行,但它不符合作者的审美观,历时六个多月仍然没能修正.其实在日常的编程中也有许多小bug的 ...
- 软件工程(FZU2015) 赛季得分榜,第七回合
SE_FZU目录:1 2 3 4 5 6 7 8 9 10 11 12 13 积分规则 积分制: 作业为10分制,练习为3分制:alpha30分: 团队项目分=团队得分+个人贡献分 个人贡献分: 个人 ...
- 并发包 concurrent(一) Atomic
1:基础概念 悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁.传 ...
- vue cli3 vue.config.js 配置详情
module.exports = { // 基本路径 baseUrl: process.env.NODE_ENV === 'production' ? '/' : '/', ...