P4097 [HEOI2013]Segment

题目描述

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

  1. 在平面上加入一条线段。记第 \(i\) 条被插入的线段的标号为 \(i\)
  2. 给定一个数 \(k\),询问与直线 \(x = k\) 相交的线段中,交点最靠上的线段的编号。

输入输出格式

输入格式:

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

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

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

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

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

输出格式:

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

说明

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

对于\(100\%\)的数据,\(1 ≤ n ≤ 10^5, 1 ≤ k, x_0, x_1 ≤ 39989, 1 ≤ y_0 ≤ y_1 ≤ 10^9\)


李超线段树

对\(x\)建线段树,每个区间存一个线段进行标记永久化。

这个线段用斜截式子\(k,b\)保存

当查询时,遍历的时候拿所有的节点进行更新。

当修改时,当完全覆盖当前区间时

  • 如果这个区间还没有线段,占上去

  • 如果这个区间上的线段和当前线段在此段无交点,选择上面的一个保留

  • 判断交点在\(mid\)左边还是右边

    • 以在左边为例

      如果当前左端点>区间左端点,当前区间保留,自己进左儿子去更新

      否则把自己留着这,把当前区间的踹下去

    • 右边同理

因为每个线段最多被划分成\(\log n\)段,所以复杂度是\(O(n\log^2 n)\)的


Code:

#include <cstdio>
#include <algorithm>
#include <cmath>
using std::max;
const int N=1e5+10;
int n=39989,m;
struct seg
{
double k,b;
int id;
seg(){}
seg(int x,int y,int xx,int yy,int Id)
{
k=1.0*(yy-y)/(1.0*(xx-x));
b=y-k*x;
id=Id;
}
double pos(double x){return k*x+b;}
}mx[N<<2];
const double eps=1e-5;
bool dcmp(double x,double y){return fabs(x-y)<eps;}
struct beecute
{
int id;double mx;
beecute(){}
beecute(int Id,double Mx){id=Id,mx=Mx;}
bool friend operator <(beecute a,beecute b){return dcmp(a.mx,b.mx)?a.id>b.id:a.mx<b.mx;}
}bee[N],las;
#define ls id<<1
#define rs id<<1|1
void change(int id,int L,int R,int l,int r,seg ins)
{
int Mid=L+R>>1;
if(l==L&&r==R)
{
if(!mx[id].id) {mx[id]=ins;return;}
double a=ins.pos(1.0*l),b=ins.pos(1.0*r),c=mx[id].pos(1.0*l),d=mx[id].pos(1.0*r);
if(a>c&&b>d) {mx[id]=ins;return;}
if(a<c&&b<d) return;
double x=(mx[id].b-ins.b)/(ins.k-mx[id].k);
if((double)(Mid)<x)
{
if(a>c)
{
change(rs,Mid+1,R,Mid+1,r,mx[id]);
mx[id]=ins;
}
else change(rs,Mid+1,R,Mid+1,r,ins);
}
else
{
if(a>c) change(ls,L,Mid,l,Mid,ins);
else
{
change(ls,L,Mid,l,Mid,mx[id]);
mx[id]=ins;
}
}
return;
}
if(r<=Mid) change(ls,L,Mid,l,r,ins);
else if(l>Mid) change(rs,Mid+1,R,l,r,ins);
else change(ls,L,Mid,l,Mid,ins),change(rs,Mid+1,R,Mid+1,r,ins);
}
void query(int id,int l,int r,int p,beecute &ret)
{
if(mx[id].id) ret=max(ret,beecute(mx[id].id,mx[id].pos(1.0*p)));
if(l==r) return;
int mid=l+r>>1;
if(p<=mid) query(ls,l,mid,p,ret);
else query(rs,mid+1,r,p,ret);
}
int main()
{
scanf("%d",&m);
for(int id=0,op,k,a,b,c,d,i=1;i<=m;i++)
{
scanf("%d",&op);
if(op)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
a=(a+las.id-1)%n+1,b=(b+las.id-1)%(int)(1e9)+1;
c=(c+las.id-1)%n+1,d=(d+las.id-1)%(int)(1e9)+1;
if(a>c) std::swap(a,c),std::swap(b,d);
if(a==c) bee[a]=max(bee[a],beecute(++id,1.0*max(b,d)));
else change(1,1,n,a,c,seg(a,b,c,d,++id));
}
else
{
scanf("%d",&k);
k=(k+las.id-1)%n+1;
las=bee[k];
query(1,1,n,k,las);
printf("%d\n",las.id);
}
}
return 0;
}

2019.2.14

洛谷 P4097 [HEOI2013]Segment 解题报告的更多相关文章

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

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

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

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

  3. [洛谷P4097] [HEOI2013] Segment

    Description 要求在平面直角坐标系下维护两个操作: 1.在平面上加入一条线段.记第 \(i\) 条被插入的线段的标号为 \(i\) 2.给定一个数 \(k\) ,询问与直线 \(x = k\ ...

  4. 洛谷 P1783 海滩防御 解题报告

    P1783 海滩防御 题目描述 WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和仓库总是被敌方派人偷袭 ...

  5. 洛谷 P4597 序列sequence 解题报告

    P4597 序列sequence 题目背景 原题\(\tt{cf13c}\)数据加强版 题目描述 给定一个序列,每次操作可以把某个数\(+1\)或\(-1\).要求把序列变成非降数列.而且要求修改后的 ...

  6. 洛谷1087 FBI树 解题报告

    洛谷1087 FBI树 本题地址:http://www.luogu.org/problem/show?pid=1087 题目描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全 ...

  7. 洛谷 P3349 [ZJOI2016]小星星 解题报告

    P3349 [ZJOI2016]小星星 题目描述 小\(Y\)是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有\(n\)颗小星星,用\(m\)条彩色的细线串了起来,每条细线连着两颗小星星. 有一 ...

  8. 洛谷 P3177 树上染色 解题报告

    P3177 [HAOI2015]树上染色 题目描述 有一棵点数为\(N\)的树,树边有边权.给你一个在\(0\) ~ \(N\)之内的正整数\(K\),你要在这棵树中选择\(K\)个点,将其染成黑色, ...

  9. 洛谷 P4705 玩游戏 解题报告

    P4705 玩游戏 题意:给长为\(n\)的\(\{a_i\}\)和长为\(m\)的\(\{b_i\}\),设 \[ f(x)=\sum_{k\ge 0}\sum_{i=1}^n\sum_{j=1}^ ...

随机推荐

  1. zookeepeer使用zkCli.sh命令

    一.连接服务器端 [root@sxl132 zookeepeer]# ./bin/zkCli. Connecting to -- ::, [myid:] - INFO [main:Environmen ...

  2. Flutter - 创建自适应的Android app 图标

    上一篇文章说到  Flutter - 自动生成Android & iOS图标 通过flutter_launcher_icons 可以一键生成所有的Icon 到此基本什么问题也没有,如果你用io ...

  3. item 7:当创建对象的时候,区分()和{}的使用

    本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 从不同的角度来看,在C++11中,对象初始化拥有多种语法选择,这体 ...

  4. 初识 tk.mybatis.mapper 通用mapper

    在博客园发表Mybatis Dynamic Query后,一位园友问我知不知道通用mapper,仔细去找了一下,还真的有啊,比较好的就是abel533写的tk.mybatis.mapper. 本次例子 ...

  5. Webpack 2 视频教程 002 - NodeJS 安装与配置

    原文发表于我的技术博客 这是我免费发布的高质量超清「Webpack 2 视频教程」. Webpack 作为目前前端开发必备的框架,Webpack 发布了 2.0 版本,此视频就是基于 2.0 的版本讲 ...

  6. Unity接入Steamworks

    一.将scrpts/Steamworks.net/SteamManager组件添加到游戏物体上 二.修改SteamManager的代码为游戏的id如图所示 三.Unity,打开项目根目录,修改stea ...

  7. 基于 CentOS 搭建 FTP 文件服务

    https://www.linuxidc.com/Linux/2017-11/148518.htm

  8. Record for Individual Project ( Word frequency program )

    1.  预计时间 ● 对问题总体的理解.规划:10 min ● 设计编写程序:5 h ● 调试: 分模块-40 min; 总体-40min ● 测试(性能分析).改进:1 h 2.  实际用时 ● 对 ...

  9. 5.1 四则运算单元测试j

    由于上个星期请假没上课,这个星期回来才知道作业,时间比较赶,个人能力又不足,作业质量不是很好 Calculator.java import java.util.Scanner; public clas ...

  10. 在web.xml中配置监听器来控制ioc容器生命周期

    5.整合关键-在web.xml中配置监听器来控制ioc容器生命周期 原因: 1.配置的组件太多,需保障单实例 2.项目停止后,ioc容器也需要关掉,降低对内存资源的占用. 项目启动创建容器,项目停止销 ...