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. vue-cli 3.0 axios 跨域请求代理配置及生产环境 baseUrl 配置

    1. 开发环境跨域配置 在 vue.config.js 文件中: module.exports = { runtimeCompiler: true, publicPath: '/', // 设置打包文 ...

  2. 一台服务器多实例mysql做主从复制

    在一台服务器上开两个端口的mysql(3306.3307),做成主从复制环境 1)安装mysql(安装过程这里就不做过多介绍) 参考:http://www.cnblogs.com/kevingrace ...

  3. 详解centos7配置本地yum源的方法

    近在使用虚拟机时遇到一些麻烦,因为公司内部有网络管理,所以vm连接不上外网,yum无法安装软件,怎么解决呢?–使用iso做本地yum源,可以解决大部份的包安装. vm安装的是centos7. 1.挂载 ...

  4. Reading Task 2 —— by12061154Joy

    关于Silver Bullet: Brooks在“No Silver Bullet”主张并断言在未来的十年之内(从1986年文章发表后开始计算),不会有任何单一的软件工程上的突破,能够让程序设计的生产 ...

  5. #个人作业Week2——结对编程对象代码复审

    General 代码能够正确运行,能够正确生成指定数量的题目和答案,并且能够对给出的题目和答案文件进行比对,输出结果. 代码没有非常复杂的逻辑,比较容易理解,但是在缺少注释的情况下有部分代码需要较长时 ...

  6. 使用highcharts绘制美观的燃尽图

    使用highcharts绘制美观的燃尽图 助教在博客中介绍了两种绘制燃尽图的方法,但是我们组在使用时发现有些任务不适合写进issue,而且网站生成的燃尽图不是很美观,因此我们打算使用其他方法自己绘制燃 ...

  7. Linux内核分析(第八周)

    进程的切换和系统的一般执行过程 一.进程切换的关键代码switch_to分析 1.进程调度与其时机分析 分类: 第一种分类 I/O-bound:频繁的进行I/O:会花很多时间等待I/O操作完成 CPU ...

  8. 四则运算安卓版ver.mk3

    在原有的基础上做了些许改动以及添加了一点小功能,以下是代码: package com.example.add; import java.io.File; import com.example.add. ...

  9. 作业6-COSPLAY孩子他家长

    为了我提高我女儿的数学能力,我以下我会根据我想要的功能做出相应的解决方案,为了孩子,父母也可以想的比老师周到.可怜天下父母心. 编号.          名称.                     ...

  10. Microsoft Orleans构建高并发、分布式的大型应用程序框架

    Microsoft Orleans 在.net用简单方法构建高并发.分布式的大型应用程序框架. 原文:http://dotnet.github.io/orleans/ 在线文档:http://dotn ...