题目描述

要求在平面直角坐标系下维护两个操作: 
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。

样例输入

6
1 8 5 10 8
1 6 7 2 6
0 2
0 9
1 4 7 6 7
0 5

样例输出

2
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——李超线段树的更多相关文章

  1. BZOJ3165: [Heoi2013]Segment(李超线段树)

    题意 题目链接 Sol 李超线段树板子题.具体原理就不讲了. 一开始自己yy着写差点写自闭都快把叉积搬出来了... 后来看了下litble的写法才发现原来可以写的这么清晰简洁Orz #include& ...

  2. 【BZOJ-3165】Segment 李超线段树(标记永久化)

    3165: [Heoi2013]Segment Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 368  Solved: 148[Submit][Sta ...

  3. Luogu P4097 [HEOI2013]Segment 李超线段树

    题目链接 \(Click\) \(Here\) 李超线段树的模板.但是因为我实在太\(Naive\)了,想象不到实现方法. 看代码就能懂的东西,放在这里用于复习. #include <bits/ ...

  4. 2019.02.11 bzoj3165: [Heoi2013]Segment(线段树)

    传送门 题意简述:要求支持两种操作: 插入一条线段. 询问与直线x=kx=kx=k相交的线段中,交点最靠上的线段的编号. 思路: 直接上李超线段树即可. 代码: #include<bits/st ...

  5. 【BZOJ 3165】 [Heoi2013]Segment 李超线段树

    所谓李超线段树就是解决此题一类的问题(线段覆盖查询点最大(小)),把原本计算几何的题目变成了简单的线段树,巧妙地结合了线段树的标记永久化与标记下传,在不考虑精度误差的影响下,打法应该是这样的. #in ...

  6. P4097 [HEOI2013]Segment 李超线段树

    $ \color{#0066ff}{ 题目描述 }$ 要求在平面直角坐标系下维护两个操作: 在平面上加入一条线段.记第 i 条被插入的线段的标号为 i 给定一个数 k,询问与直线 x = k 相交的线 ...

  7. BZOJ.3165.[HEOI2013]Segment(李超线段树)

    BZOJ 洛谷 对于线段,依旧是存斜率即可. 表示精度误差一点都不需要管啊/托腮 就我一个人看成了mod(10^9+1)吗.. //4248kb 892ms #include <cstdio&g ...

  8. Segment 李超线段树

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

  9. 【洛谷P4097】Segment 李超线段树

    题目大意:维护一个二维平面,给定若干条线段,支持询问任意整数横坐标处对应的纵坐标最靠上的线段的 id,相同高度取 id 值较小的,强制在线. 题解:初步学习了李超线段树.李超线段树的核心思想在于通过标 ...

随机推荐

  1. SCOI2019d1t1平台跳跃[高精]

    分析 首先考虑相邻柱子之间没有浮台. 记前 \(m-1\) 个盘子为 x, 第 \(m\) 个盘子为 y,有如下过程:\(x\rightarrow C, y\rightarrow B, x\right ...

  2. 图解Redis之数据结构篇——链表

    前言     Redis链表为双向无环链表!     图解Redis之数据结构篇--简单动态字符串SDS提到Redis使用了简单动态字符串,链表,字典(散列表),跳跃表,整数集合,压缩列表这些数据结构 ...

  3. Python学习之赋值列表

    # the program aim to differentiate the defference of a=b or a=b[:] my_fruits=["apple",&quo ...

  4. Consecutive Subsequence CodeForces - 977F (map优化DP)·

    You are given an integer array of length nn. You have to choose some subsequence of this array of ma ...

  5. 阿里字体css代码引入方法

    1.第一步,选择自己想要的图标字体,添加入库. 2.选择下载代码. 3.我们可以发现,有如下的代码被下载下来了. 4.我们选择iconfont.css放到自己的文件夹中. 5.然后我们根据下载下来ht ...

  6. Spring Data Elasticsearch 和 x-pack 用户名/密码验证连接

    Elasticsearch Java API 客户端连接 一个是TransportClient,一个是NodeClient,还有一个XPackTransportClient TransportClie ...

  7. elasticsearch5.0版本的head安装

    elasticsearch5.0版本的head安装 elasticsearch5.0版本由于刚出不久,并且与2.0版本的差距较大.所以,目前大家对5.0的一些使用还有所陌生.这里先把关于head插件的 ...

  8. CSS颜色代码 颜色值 颜色名字大全

    颜色值 CSS 颜色使用组合了红绿蓝颜色值 (RGB) 的十六进制 (hex) 表示法进行定义.对光源进行设置的最低值可以是 0(十六进制 00).最高值是 255(十六进制 FF).从 0 到 25 ...

  9. 访问修饰符 public private protected default

  10. 【问题解决方案】之 Word 公式编辑器 使用小tips

    输入空格:shift+Ctrl+space 换行:直接回车.之后在上方菜单栏中选择"在等号处对齐"