Description

要求在平面直角坐标系下维护两个操作:

1.在平面上加入一条线段。记第 \(i\) 条被插入的线段的标号为 \(i\)

2.给定一个数 \(k\) ,询问与直线 \(x = k\) 相交的线段中,交点最靠上的线段的编号。

Input

第一行一个整数 \(n\),表示共 \(n\) 个操作

接下来 \(n\) 行,每行第一个数为 \(0\) 或 \(1\)

若该数为 \(0\),则后面跟着一个正整数 \(k\),表示询问与直线 \(x = ((k + lastans – 1) \% 39989+1)\) 相交的线段中交点(包括在端点相交的情形)最靠上的线段的编号,其中 \(\%\) 表示取余。若某条线段为直线的一部分,则视作直线与线段交于该线段 \(y\) 坐标最大处。若有多条线段符合要求,输出编号最小的线段的编号

若该数为 \(1\),则后面跟着四个正整数 \(x0\), \(y0\), \(x1\), \(y1\),表示插入一条两个端点为 \(((x0+lastans-1) \% 39989+1\), \((y0+lastans-1) \%10^9+1)\) 和 \(((x1+lastans-1) \% 39989+1\) , \((y1+lastans-1) \%10^9+1)\) 的线段

其中 $lastans $ 为上一次询问的答案。初始时 \(lastans=0\)

Output

对于每个 \(0\) 操作,输出一行,包含一个正整数,表示交点最靠上的线段的编号。若不存在与直线相交的线段,答案为 \(0\)

Sample Input

6

1 8 5 10 8

1 6 7 2 6

0 2

0 9

1 4 7 6 7

0 5

Sample Output

2

0

3

HINT

对于 \(30\%\) 的数据,\(n \leq 1000\)

对于 \(100\%\) 的数据,\(1 \leq n \leq 10^5, 1 \leq k, x0, x1 \leq 39989, 1 \leq y0 , y1 \leq 10^9\)


题解

李超线段树模板题。

推荐一篇好的 \(blog\) : https://blog.csdn.net/flere825/article/details/76283734

很巧妙的思想。

关键点就是引入区间“最优势线段” & 动态维护它,保证对每一个位置,答案一定在包含这个位置的区间的“最优势线段”中。


代码

注意坑点!!!!!

\(y\) 的模数为 \(10^9\)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath> #define eps 1e-9
#define P 39989 using namespace std; int read(){
int x=0;
char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
return x;
} const int N = 100005;
typedef double db; int tot;
db K[N],B[N];
struct node{
node *ch[2];
int id;
}pool[P*2],*root;
int cnt;
void build(node *p,int l,int r){
p->id=0;
if(l==r) return;
int mid=(l+r)>>1;
build(p->ch[0]=&pool[++cnt],l,mid);
build(p->ch[1]=&pool[++cnt],mid+1,r);
}
inline db cal(int x,int c) { return K[x]*c+B[x]; }
bool better(int x,int y,int c){
if(x==0) return false;
if(y==0) return true;
db cx=cal(x,c),cy=cal(y,c);
if(fabs(cx-cy)<eps) return x<y;
return cx>cy;
}
void insert(node *p,int l,int r,int L,int R,int c){
if(l==L && r==R){
int mid=(l+r)>>1;
if(better(c,p->id,mid)) swap(p->id,c);
int tl=better(p->id,c,l),tr=better(p->id,c,r);
if(!c || l==r || (tl && tr)) return;
if(tl) insert(p->ch[1],mid+1,r,mid+1,r,c);
else insert(p->ch[0],l,mid,l,mid,c);
return;
}
int mid=(l+r)>>1;
if(R<=mid) insert(p->ch[0],l,mid,L,R,c);
else if(L>mid) insert(p->ch[1],mid+1,r,L,R,c);
else {
insert(p->ch[0],l,mid,L,mid,c);
insert(p->ch[1],mid+1,r,mid+1,R,c);
}
}
int ans;
void query(node *p,int l,int r,int c){
ans = better(p->id,ans,c) ? p->id : ans ;
if(l==r) return;
int mid=(l+r)>>1;
if(c<=mid) query(p->ch[0],l,mid,c);
else query(p->ch[1],mid+1,r,c);
} int main()
{
int n,opt,lastans=0,k,x0,y0,x1,y1;
n=read(); root=&pool[++cnt];
build(root,1,P); while(n--){
opt=read();
if(opt==0){
k=(read()+lastans-1)%P+1;
ans=0;
query(root,1,P,k);
lastans=ans;
printf("%d\n",lastans);
}
else{
x0=(read()+lastans-1)%P+1; y0=(read()+lastans-1)%1000000000+1;
x1=(read()+lastans-1)%P+1; y1=(read()+lastans-1)%1000000000+1;
if(x0>x1) swap(x0,x1),swap(y0,y1);
tot++;
K[tot]=1.0*(y1-y0)/(x1-x0);
B[tot]=y0-K[tot]*x0;
insert(root,1,P,x0,x1,tot);
}
} return 0;
}

[洛谷P4097] [HEOI2013] Segment的更多相关文章

  1. 洛谷 P4097 [HEOI2013]Segment 解题报告

    P4097 [HEOI2013]Segment 题目描述 要求在平面直角坐标系下维护两个操作: 在平面上加入一条线段.记第 \(i\) 条被插入的线段的标号为 \(i\) 给定一个数 \(k\),询问 ...

  2. 2018.07.23 洛谷P4097 [HEOI2013]Segment(李超线段树)

    传送门 给出一个二维平面,给出若干根线段,求出x" role="presentation" style="position: relative;"&g ...

  3. 洛谷P4097 [HEOI2013]Segment(李超线段树)

    题面 传送门 题解 调得咱自闭了-- 不难发现这就是个李超线段树,不过因为这里加入的是线段而不是直线,所以得把线段在线段树上对应区间内拆开之后再执行李超线段树的操作,那么复杂度就是\(O(n\log^ ...

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

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

  5. 洛谷 P4100 [HEOI2013]钙铁锌硒维生素 解题报告

    P4100 [HEOI2013]钙铁锌硒维生素 题目描述 银河队选手名单出来了!小林,作为特聘的营养师,将负责银河队选手参加 宇宙比赛的饮食. 众所周知,前往宇宙的某个星球,通常要花费好长好长的时间, ...

  6. P4097 [HEOI2013]Segment(李超树)

    链接 https://www.luogu.org/problemnew/show/P4097 https://www.lydsy.com/JudgeOnline/problem.php?id=3165 ...

  7. 【题解】Luogu P4097 [HEOI2013]Segment

    原题传送门 这珂以说是李超线段树的模板题 按着题意写就行了,时间复杂度为\(O(n\log^2n)\) #include <bits/stdc++.h> #define N 40005 # ...

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

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

  9. 题解——洛谷P4095 [HEOI2013]Eden 的新背包问题(背包)

    思路很妙的背包 用了一些前缀和的思想 去掉了一个物品,我们可以从前i-1个和后i+1个推出答案 奇妙的思路 #include <cstdio> #include <algorithm ...

随机推荐

  1. H3C生成树协议

  2. CF1146G Zoning Restrictions

    CF1146G Zoning Restrictions 网络流 h<=50? 直接都选择最大的,ans=n*h*h 最小割 考虑舍弃或者罚款 有一个>x就要罚款? 经典取值限制的模型:切糕 ...

  3. 一眼看懂promise async的区别

    // promise方法 let p1 = new Promise((resolve,reject) => { setTimeout(() => { resolve('我是p1') },4 ...

  4. 1134 最长上升子序列 (序列型 DP)

    思路: 由于一般的动态规划时间复杂度是O(n^2)(哈哈哈哈 第一次用的就是这个!)用在这里由于n最大为50000 所以会超时 到这里我们可以用一个数组来动态维护这个最长上升的子序列,将你要输入的子序 ...

  5. JQuery仿购物网站放大镜特效所遇问题及思考

    JQuery仿购物网站放大镜特效所遇问题及思考 先贴下效果图,然后描述起来也就不会不知道我在说什么了. 我碰到的问题一: 一开始我自己总结了是因为两个小原因导致的①使用了mouseover,mouse ...

  6. java_回文检测

    package bao; import java.util.Scanner; public class Work { public static boolean digui(String str1,i ...

  7. 0019 盒子模型(CSS重点):边框、内外边距、布局稳定性、PS

    typora-copy-images-to: media 第01阶段.前端基础.盒子模型 盒子模型(CSS重点) css学习三大重点: css 盒子模型 . 浮动 . 定位 主题思路: 目标: 理解: ...

  8. 006 管理Ceph的RBD块设备

    一, Ceph RBD的特性 支持完整和增量的快照 自动精简配置 写时复制克隆 动态调整大小 二.RBD基本应用 2.1 创建RBD池 [root@ceph2 ceph]# ceph osd pool ...

  9. pytorch :: Dataloader中的迭代器和生成器应用

    在使用pytorch训练模型,经常需要加载大量图片数据,因此pytorch提供了好用的数据加载工具Dataloader. 为了实现小批量循环读取大型数据集,在Dataloader类具体实现中,使用了迭 ...

  10. knn识别简单验证码

    参考 https://www.biaodianfu.com/knn-captcha-recognition.html 内容大致一样,只是根据自己的想法加入了一些改动 KNN(k近邻算法) 算法原理请看 ...