Luogu P4097 [HEOI2013]Segment 李超线段树
题目链接 \(Click\) \(Here\)
李超线段树的模板。但是因为我实在太\(Naive\)了,想象不到实现方法。
看代码就能懂的东西,放在这里用于复习。
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
#define ls (p << 1)
#define rs (p << 1 | 1)
#define mid ((l + r) >> 1)
struct Node {
    int l, r, id;
    double yl, yr;
    Node (int x1 = 0, int y1 = 0, int x2 = 0, int y2 = 0, int i = 0) {
        l = x1, r = x2, yl = y1, yr = y2, id = i;
        if (l == r) {
			yl = yr = max (yl, yr);
		}
    }
    double get (int x) {return l == r ? yl : yl + (k () * (x - l));}
    double k () {return (yr - yl) / (r - l);}
    void lm (int x) {yl = get (x); l = x;}
    void rm (int x) {yr = get (x); r = x;}
};
bool hei (Node a, Node b, int x) {
    return a.get (x) == b.get (x) ? a.id < b.id : a.get (x) > b.get (x);
}
struct St {
    Node tree[N << 2];
	void build (int l, int r, int p) {
        tree[p].l = l;
		tree[p].r = r;
        if (l == r) return;
        build (l, mid, ls);
        build (mid + 1, r, rs);
    }
    Node query (int t, int l, int r, int p) {
        if (l == r) return tree[p];
		Node res;
        if (t <= mid) {
			res = query (t, l, mid, ls);
        } else {
			res = query (t, mid + 1, r, rs);
		}
		return hei (res, tree[p], t) ? res : tree[p];
    }
    void update (int l, int r, Node k, int p) {
        if (tree[p].l > k.l) k.lm (tree[p].l);
        if (tree[p].r < k.r) k.rm (tree[p].r); //削足适履
        if (hei (k, tree[p], mid)) swap (tree[p], k); //让tree[p]在mid上具有优势
        if (min (tree[p].yl, tree[p].yr) >= max (k.yl, k.yr)) return; //如果完全覆盖
        if (l == r) return; //如果大小为1
        if (tree[p].k () <= k.k ()) {
			update (mid + 1, r, k, rs); //如果k在后面有露出来的情况
        } else {
			update (l, mid, k, ls); //如果k在前面有露出来的情况
		}
	}
    void insert (int l, int r, Node k, int p) {
        if (k.l > r || k.r < l) return;
        if (tree[p].l > k.l) k.lm (tree[p].l);
        if (tree[p].r < k.r) k.rm (tree[p].r);
        if (l == k.l && r == k.r) {
			update (l, r, k, p);
			return;
		}
		//把node一路传下去,对应区间就削成对应大小的线段
        if (l == r) return;
		insert (l, mid, k, ls);
		insert (mid + 1, r, k, rs);
    }
}T;
const int My = 1e9;
const int Mx = 39989;
int m, k, la, Ind, opt;
int main () {
    T.build (1, Mx, 1);
    cin >> m;
    while (m--) {
        cin >> opt;
        if (opt == 0) {
            cin >> k;
            k = (k + la - 1) % Mx + 1;
            la = T.query (k, 1, Mx, 1).id;
            cout << la << endl;
        } else {
            int x0, x1, y0, y1;
            cin >> x0 >> y0 >> x1 >> y1;
            x0 = (x0 + la - 1) % Mx + 1;
			x1 = (x1 + la - 1) % Mx + 1;
            y0 = (y0 + la - 1) % My + 1;
			y1 = (y1 + la - 1) % My + 1;
            if (x0 > x1) {
				swap (x0, x1);
				swap (y0, y1);
			}
            Node res = Node (x0, y0, x1, y1, ++Ind);
            T.insert (1, Mx, res, 1);
        }
    }
}
Luogu P4097 [HEOI2013]Segment 李超线段树的更多相关文章
- P4097 [HEOI2013]Segment  李超线段树
		$ \color{#0066ff}{ 题目描述 }$ 要求在平面直角坐标系下维护两个操作: 在平面上加入一条线段.记第 i 条被插入的线段的标号为 i 给定一个数 k,询问与直线 x = k 相交的线 ... 
- 【洛谷P4097】Segment 李超线段树
		题目大意:维护一个二维平面,给定若干条线段,支持询问任意整数横坐标处对应的纵坐标最靠上的线段的 id,相同高度取 id 值较小的,强制在线. 题解:初步学习了李超线段树.李超线段树的核心思想在于通过标 ... 
- BZOJ3165: [Heoi2013]Segment(李超线段树)
		题意 题目链接 Sol 李超线段树板子题.具体原理就不讲了. 一开始自己yy着写差点写自闭都快把叉积搬出来了... 后来看了下litble的写法才发现原来可以写的这么清晰简洁Orz #include& ... 
- 【BZOJ 3165】 [Heoi2013]Segment 李超线段树
		所谓李超线段树就是解决此题一类的问题(线段覆盖查询点最大(小)),把原本计算几何的题目变成了简单的线段树,巧妙地结合了线段树的标记永久化与标记下传,在不考虑精度误差的影响下,打法应该是这样的. #in ... 
- BZOJ3165[Heoi2013]Segment——李超线段树
		题目描述 要求在平面直角坐标系下维护两个操作: 1.在平面上加入一条线段.记第i条被插入的线段的标号为i. 2.给定一个数k,询问与直线 x = k相交的线段中,交点最靠上的线段的编号. 输入 第一行 ... 
- BZOJ.3165.[HEOI2013]Segment(李超线段树)
		BZOJ 洛谷 对于线段,依旧是存斜率即可. 表示精度误差一点都不需要管啊/托腮 就我一个人看成了mod(10^9+1)吗.. //4248kb 892ms #include <cstdio&g ... 
- 【BZOJ-3165】Segment      李超线段树(标记永久化)
		3165: [Heoi2013]Segment Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 368 Solved: 148[Submit][Sta ... 
- 【题解】Luogu P4097 [HEOI2013]Segment
		原题传送门 这珂以说是李超线段树的模板题 按着题意写就行了,时间复杂度为\(O(n\log^2n)\) #include <bits/stdc++.h> #define N 40005 # ... 
- 2019.02.11 bzoj3165: [Heoi2013]Segment(线段树)
		传送门 题意简述:要求支持两种操作: 插入一条线段. 询问与直线x=kx=kx=k相交的线段中,交点最靠上的线段的编号. 思路: 直接上李超线段树即可. 代码: #include<bits/st ... 
随机推荐
- 三、zookeeper安装
			一.简介 二.下载解压: #wget http://mirrors.hust.edu.cn/apache/zookeeper/zookeeper-3.4.12/zookeeper-3.4.12.tar ... 
- 二、Docker部署应用
			一.有关Docker的安装请参考docker官网 Docker 提供了两个版本:社区版 (CE) 和企业版 (EE). Docker 社区版 (CE) 是开发人员和小型团队开始使用 Docker 并 ... 
- LODOP中page-break-before:always给div分页
			Lodop中超过超文本打印项高度会自动分页:Lodop打印控件 超文本自动分页Lodop中还有NewPage和NewPageA,用于手动分页:Lodop强制分页LODOP.NewPage()和LODO ... 
- nginx 负载均衡(默认算法)
			使用 nginx 的upstream模块只需要几步就可以实现一个负载均衡: 在 nginx 配置文件中添加两个server server { listen ; server_name 192.168. ... 
- sql中的begin catch 。。。end catch 的用法
			begin catch ...end catch 是用来处理异常的 begintry--SQLendtry begincatch--sql (处理出错动作)endcatch 我们将可能会出错的sql ... 
- webpack 打包编译-webkit-box-orient: vertical 后消失
			/* autoprefixer: off */ -webkit-box-orient: vertical; // 参考 https://github.com/postcss/autoprefixer/ ... 
- Let's Encrypt免费泛域名证书申请
			一. 下载acme.sh,以下四条命令任选一条即可 curl https://get.acme.sh | shwget -O - https://get.acme.sh | sh curl https ... 
- crontab 任务带日期输出
			date命令用法#带格式输出$ date +"%Y-%m-%d"#输出1天后的日期$ date -d "1 day" +"%Y-%m-%d" ... 
- [CF1131C]Birthday【贪心】
			题目描述 有 n n个数摆放在一个环形中(最后一个与第一个相邻),需要改变这些数的顺序,使得相邻两个数的最大绝对差最小.如果有多种最佳方案,输出任意一种. (翻译来自洛谷) 分析 首先收尾相接,那么很 ... 
- HR_Two Strings
			https://www.hackerrank.com/challenges/two-strings/problem?h_l=interview&playlist_slugs%5B%5D=int ... 
