题目大意:维护一个二维平面,给定若干条线段,支持询问任意整数横坐标处对应的纵坐标最靠上的线段的 id,相同高度取 id 值较小的,强制在线。

题解:初步学习了李超线段树。李超线段树的核心思想在于通过标记永久化的方式来维护斜率。

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const double eps=1e-6; inline int read(){
int x=0,f=1;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
return f*x;
} int n,lastans,cnt;
struct line{double k,b;int id;};
struct node{
#define ls(x) t[x].lc
#define rs(x) t[x].rc
int lc,rc;bool tag;line s;
}t[maxn];
int tot,root;
void pushdown(int o,int l,int r,line now){
if(!t[o].tag){t[o].s=now,t[o].tag=1;return;}
double l1=now.k*l+now.b,r1=now.k*r+now.b;
double l2=t[o].s.k*l+t[o].s.b,r2=t[o].s.k*r+t[o].s.b;
if(l2>=l1&&r2>=r1)return;
else if(l1>=l2&&r1>=r2){t[o].s=now;return;}
else{
double pos=(now.b-t[o].s.b)/(t[o].s.k-now.k);
int mid=l+r>>1;
if(pos<=mid)pushdown(ls(o),l,mid,r1>r2?t[o].s:now);
else pushdown(rs(o),mid+1,r,r1>r2?now:t[o].s);
if((l1>l2&&pos>mid)||(pos<=mid&&r1>r2))t[o].s=now;
}
}
int build(int l,int r){
int x=++tot;
if(l==r)return x;
int mid=l+r>>1;
ls(x)=build(l,mid),rs(x)=build(mid+1,r);
return x;
}
void modify(int o,int l,int r,int x,int y,line now){
if(l==x&&r==y){pushdown(o,l,r,now);return;}
int mid=l+r>>1;
if(y<=mid)modify(ls(o),l,mid,x,y,now);
else if(x>mid)modify(rs(o),mid+1,r,x,y,now);
else modify(ls(o),l,mid,x,mid,now),modify(rs(o),mid+1,r,mid+1,y,now);
}
line query(int o,int l,int r,int pos){
if(l==r)return t[o].tag?t[o].s:line{0,0,0};
int mid=l+r>>1;
line res=pos<=mid?query(ls(o),l,mid,pos):query(rs(o),mid+1,r,pos);
if(!t[o].tag)return res;
double v1=t[o].s.k*pos+t[o].s.b,v2=res.k*pos+res.b;
if(!res.id||v1>v2||(fabs(v1-v2)<eps&&t[o].s.id<res.id))res=t[o].s;
return res;
} void solve(){
n=read();
root=build(1,39989);
while(n--){
int opt=read();
if(opt==0){
int pos=(read()+lastans-1)%39989+1;
printf("%d\n",lastans=query(root,1,39989,pos).id);
}else{
int x0=read(),y0=read(),x1=read(),y1=read();
x0 = (x0 + lastans - 1) % 39989 + 1;
x1 = (x1 + lastans - 1) % 39989 + 1;
y0 = (y0 + lastans - 1) % (int) (1e9) + 1;
y1 = (y1 + lastans - 1) % (int) (1e9) + 1;
if(x0==x1)modify(root,1,39989,x0,x1,line{0.0,max(y0,y1),++cnt});
else{
if(x0>x1)swap(x0,x1),swap(y0,y1);
double k=(double)(y0-y1)/(x0-x1),b=(double)y0-k*x0;
modify(root,1,39989,x0,x1,line{k,b,++cnt});
}
}
}
} int main(){
solve();
return 0;
}

【洛谷P4097】Segment 李超线段树的更多相关文章

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

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

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

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

  3. Segment 李超线段树

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

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

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

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

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

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

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

  7. 【BZOJ】1012: [JSOI2008]最大数maxnumber /【洛谷】1198(线段树)

    Description 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2. 插 ...

  8. 洛谷题解P4314CPU监控--线段树

    题目链接 https://www.luogu.org/problemnew/show/P4314 https://www.lydsy.com/JudgeOnline/problem.php?id=30 ...

  9. 洛谷P3372/poj3468(线段树lazy_tag)(询问区间和,支持区间修改)

    洛谷P3372 //线段树 询问区间和,支持区间修改 #include <cstdio> using namespace std; struct treetype { int l,r; l ...

随机推荐

  1. Linux下IP SAN共享存储操作记录

    一.简单介绍SAN,即存储区域网络(storage area network and SAN protocols),它是一种高速网络实现计算机与存储系统之间的数据传输.常见的分类是FC-SAN和IP- ...

  2. vue 动态修改 css

    <div v-for="i in resultDate" v-if="i.ProjectId>='4'" @click=EveyTesttInfo( ...

  3. 移动app rem

    (function (doc, win) { var docEl = doc.documentElement, resizeEvt = 'orientationchange' in window ? ...

  4. 如何在java项目中使用lucene

    lucene是一个开源的全文检索引擎工具包,但它不是一个成型的搜索引擎,它的功能就是负责将文本数据按照某种分词算法进行分词,分词后的结果存储在索引库中,然后根据关键字从索引库检检索. 那么应该如何使用 ...

  5. Maven入门系列(一):Eclipse中使用Maven

    Maven下载和安装 在使用Maven之前首先先要下载Mavne的免安装包,下载地址:http://maven.apache.org/download.cgi 想看源码的可以下载src版本,使用的下载 ...

  6. wordpress升级出错

    服务器是腾讯云 搜索到的解决方案有几个,试了好几个,不知道哪个是根本原因,反正都操作了. 设置wordpress文件夹和子文件夹的权限 编辑wp-config.php,在文末添加如下: define( ...

  7. Java代码安全

    https://www.owasp.org/index.php/Category:Java

  8. laravel5 报错419,form 添加crrf_field 后让然失败,本地环境配置问题

    这个是因为laravel自带CSRF验证的问题 解决方法 方法一:去关掉laravel的csrf验证,但这个人不建议,方法也不写出来了. 方法二:把该接口写到api.php上就好了 方法三: 首先在页 ...

  9. Linux基础学习(3)--初学注意

    第三章——初学注意 一.学习Linux的注意事项 1.Linux严格区分大小写 2.Linux中所有内容以文件形式保存,包括硬件: (1)硬盘文件是/dev/sd[a-p] (2)光盘文件是/dev/ ...

  10. Lodop设置打印维护返回打印语句代码

    打印设计关闭时,可以返回设计的打印代码,打印维护则返回成功打印的次数.不过打印维护也是返回打印程序代码的,方法就是加个语句,这个语句是: LODOP.SET_PRINT_MODE("PRIN ...