BZOJ 3165: [Heoi2013]Segment
3165: [Heoi2013]Segment
Time Limit: 40 Sec Memory Limit: 256 MB
Submit: 465 Solved: 187
[Submit][Status][Discuss]
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, 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。
Output
对于每个 0操作,输出一行,包含一个正整数,表示交点最靠上的线段的编号。若不存在与直线相交的线段,答案为0。
Sample Input
1 8 5 10 8
1 6 7 2 6
0 2
0 9
1 4 7 6 7
0 5
Sample Output
0 3
HINT
对于100%的数据,1 ≤ n ≤ 10^5 , 1 ≤ k, x0, x1 ≤ 39989, 1 ≤ y0 ≤ y1 ≤ 10^9。
Source
线段树维护线段,23333
#include <bits/stdc++.h> struct line
{
int lt, rt;
double k, b; line(void) {}; line(int x0, int y0, int x1, int y1)
{
if (x0 < x1)
lt = x0, rt = x1;
else
lt = x1, rt = x0; if (x0 == x1)
{
k = 0.0;
b = y0 > y1 ? y0 : y1;
}
else
{
k = 1.0 * (y0 - y1) / (x0 - x1);
b = y0 - x0 * k;
}
} inline double f(int x)
{
return k * x + b;
}
}ln[]; int tot; int sg(double x)
{
static const double eps = 1e-; return (x > -eps) - (x < +eps);
} int cross(int i, int j)
{
return floor((ln[i].b - ln[j].b) / (ln[j].k - ln[i].k));
} int flg[]; int wi[]; double wy[]; inline void update(int x, int p)
{
double y = ln[p].f(x); int s = sg(y - wy[x]); if (!wi[x] || s > || (!s && p < wi[x]))
wi[x] = p, wy[x] = y;
} void insert(int t, int l, int r, int p)
{
if (ln[p].lt <= l && ln[p].rt >= r)
{
if (!flg[t])flg[t] = p;
else
{
int mid = (l + r) >> ; bool lu = sg(ln[p].f(l) - ln[flg[t]].f(l)) > ;
bool ru = sg(ln[p].f(r) - ln[flg[t]].f(r)) > ; if (lu && ru)flg[t] = p;
else if (lu || ru)
{
int tt = cross(p, flg[t]);
if (tt <= mid)
{
if (lu)
insert(t << , l, mid, p);
else
insert(t << , l, mid, flg[t]), flg[t] = p;
}
else
{
if (ru)
insert(t << | , mid + , r, p);
else
insert(t << | , mid + , r, flg[t]), flg[t] = p;
}
}
else
{
update(l, p);
update(r, p);
}
}
}
else
{
int mid = (l + r) >> ; if (ln[p].lt <= mid)
insert(t << , l, mid, p);
if (ln[p].rt > mid)
insert(t << | , mid + , r, p);
}
} int ansi; double ansy; void query(int t, int l, int r, int x)
{
if (flg[t])
{
double y = ln[flg[t]].f(x); int s = sg(y - ansy); if (s > || (!s && flg[t] < ansi))
ansi = flg[t], ansy = y;
} if (l != r)
{
int mid = (l + r) >> ; if (x <= mid)
query(t << , l, mid, x);
if (x > mid)
query(t << | , mid + , r, x);
}
} signed main(void)
{
int n; scanf("%d", &n); for (int ans = ; n--; )
{
int op; scanf("%d", &op); if (op) // insert segment
{
int x0, y0, x1, y1; scanf("%d%d%d%d", &x0, &y0, &x1, &y1); x0 = (x0 + ans - ) % + ;
x1 = (x1 + ans - ) % + ;
y0 = (y0 + ans - ) % + ;
y1 = (y1 + ans - ) % + ; ln[++tot] = line(x0, y0, x1, y1); insert(, , , tot);
}
else // query segment
{
int x; scanf("%d", &x); x = (x + ans - ) % + ; ansi = wi[x], ansy = wy[x]; query(, , , x); printf("%d\n", ans = ansi);
}
}
}
@Author: YouSiki
BZOJ 3165: [Heoi2013]Segment的更多相关文章
- bzoj 3165: [Heoi2013]Segment 动态凸壳
3165: [Heoi2013]Segment Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 202 Solved: 89[Submit][Stat ...
- Bzoj 3165 [Heoi2013]Segment题解
3165: [Heoi2013]Segment Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 668 Solved: 276[Submit][Sta ...
- BZOJ.3165.[HEOI2013]Segment(李超线段树)
BZOJ 洛谷 对于线段,依旧是存斜率即可. 表示精度误差一点都不需要管啊/托腮 就我一个人看成了mod(10^9+1)吗.. //4248kb 892ms #include <cstdio&g ...
- bzoj 3165: [Heoi2013]Segment 线段树
题目: Description 要求在平面直角坐标系下维护两个操作: 在平面上加入一条线段.记第i条被插入的线段的标号为i. 给定一个数k,询问与直线 x = k相交的线段中,交点最靠上的线段的编号. ...
- 【BZOJ3165】[HEOI2013]Segment(李超线段树)
[BZOJ3165][HEOI2013]Segment(李超线段树) 题面 BZOJ 洛谷 题解 似乎还是模板题QwQ #include<iostream> #include<cst ...
- 洛谷 P4097 [HEOI2013]Segment 解题报告
P4097 [HEOI2013]Segment 题目描述 要求在平面直角坐标系下维护两个操作: 在平面上加入一条线段.记第 \(i\) 条被插入的线段的标号为 \(i\) 给定一个数 \(k\),询问 ...
- 【BZOJ 3165】 [Heoi2013]Segment 李超线段树
所谓李超线段树就是解决此题一类的问题(线段覆盖查询点最大(小)),把原本计算几何的题目变成了简单的线段树,巧妙地结合了线段树的标记永久化与标记下传,在不考虑精度误差的影响下,打法应该是这样的. #in ...
- 【BZOJ 3165】【HEOI 2013】Segment
往区间上覆盖一次函数,做法是用线段树维护标记永久化. 每次都忘了线段树要4倍空间,第一次交总是RE,再这么手残的话考场上就真的要犯逗了. #include<cstdio> #include ...
- BZOJ 3165 Segment
同上题. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm&g ...
随机推荐
- alibaba/fescar 阿里巴巴 开源 分布式事务中间件
Fescar 是 阿里巴巴 开源的 分布式事务中间件,以 高效 并且对业务 0 侵入 的方式,解决 微服务 场景下面临的分布式事务问题. 示例:https://github.com/windwant/ ...
- Linux速成(一)
全部转载自http://www.runoob.com/linux/linux-intro.html 一.Linux 简介 Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和 ...
- Windows下LimeSDR Mini使用说明
本文内容.开发板及配件仅限用于学校或科研院所开展科研实验! 淘宝店铺名称:开源SDR实验室 LimeSDR链接:https://item.taobao.com/item.htm?spm=a230r.1 ...
- 从零开始的Python学习Episode 20——面向对象(3)
面向对象之封装 封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别:将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体. 隐藏 在python中用双下划线开 ...
- notion笔记
不错的笔记应用, 模式新颖, 正在使用, 如有相同使用者可以入群交流 notion QQ群 725638123
- cp命令详解
基础命令学习目录首页 http://man.linuxde.net/cp 如果把一个文件复制到一个目标文件中,而目标文件已经存在,那么,该目标文件的内容将被破坏.此命令中所有参数既可以是绝对路径名,也 ...
- Scrum立会报告+燃尽图(十二月六日总第三十七次):程序功能逻辑优化
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2284 项目地址:https://git.coding.net/zhang ...
- (第十一周)Beta—review阶段成员贡献分
项目名:食物链教学工具 组名:奋斗吧兄弟 组长:黄兴 组员:李俞寰.杜桥.栾骄阳.王东涵 个人贡献分=基础分+表现分 基础分=5*5*0.5/5=2.5 成员得分如下: 成员 基础分 表现分 个人贡献 ...
- 第10章 系统级I/O(下)
10.7 I/O重定向 Unix外壳提供了I/O重定向操作符,允许用户将磁盘文件和标准输出输入联系起来. 例如:unix>ls>foo.txt,使得外壳加载和执行ls程序,将标准输出重定 ...
- WPF自学入门(十二)WPF MVVM模式提取函数
我们平时在写代码时为了不重复写代码,会进行复制代码或者写通用方法.今天我们就来把上传做的函数提取成为通用的方法调用.把上次写的函数提取为两个主要的文件:ObserableObject和RelayCom ...