传说中的“李超树”。

大意:给你若干线段,试求横坐标x上的最上方一条线段的编号。无则输出零。

解:用线段树维护。

插入的时候保存自己这个区间上可能成为最大值的线段,被抛弃的则看情况下放。

查询时从最底层向上查一路,沿途取得答案。

函数我用的是斜截式来存,脑残的把b写错了.....getY还传错参了。

调掉之后就一发AC!哈哈哈

 #include <cstdio>
#include <algorithm>
#include <cmath>
const int N = , M = , INF = 0x3f3f3f3f;
const double eps = 1e-; struct SG {
double k, b;
int l, r;
}sg[M]; inline double getY(int a, int x) {
SG t = sg[a];
if(x < t.l || t.r < x || !a) {
return (double)(-INF);
}
if(fabs(t.k - INF) < eps) {
return t.b;
}
return t.k * x + t.b;
} struct SegmentTree {
int ans[N << ]; void add(int L, int R, int v, int l, int r, int o) {
//printf("add : %d %d %d %d %d \n", L, R, v, l, r);
int mid = (l + r) >> ;
if(L <= l && r <= R) {
if(!ans[o]) { /// no segment
ans[o] = v;
//printf("ans[] = %d \n", ans[o]);
return;
}
if(l == r) { /// only one
if(getY(v, r) > getY(ans[o], r)) {
ans[o] = v;
//printf("ans[] = %d \n", ans[o]);
}
return;
}
double A = getY(v, l), B = getY(v, mid), C = getY(v, r);
double D = getY(ans[o], l), E = getY(ans[o], mid), F = getY(ans[o], r);
if(A > D && C > F) {
ans[o] = v;
//printf("ans[] = %d \n", ans[o]);
return;
}
/*if(v == 3 && l == 4 && r == 5) {
printf("B = %lf E = %lf\n", B, D);
}*/
if(!(A > D) && !(C > F)) {
return;
}
if(B > E) {
if(sg[v].k > sg[ans[o]].k) {
add(l, mid, ans[o], l, mid, o << );
ans[o] = v;
//printf("ans[] = %d \n", ans[o]);
}
else {
add(mid + , r, ans[o], mid + , r, o << | );
ans[o] = v;
//printf("ans[] = %d \n", ans[o]);
}
}
else {
if(sg[v].k > sg[ans[o]].k) {
add(mid + , r, v, mid + , r, o << | );
}
else {
add(l, mid, v, l, mid, o << );
}
}
return;
}
if(L <= mid) {
add(L, R, v, l, mid, o << );
}
if(mid < R) {
add(L, R, v, mid + , r, o << | );
}
return;
}
int ask(int p, int l, int r, int o) {
if(l == r) {
//printf("ask: %d %d %d return %d \n", p, l, r, ans[o]);
return ans[o];
}
int mid = (l + r) >> ;
int A;
if(p <= mid) {
A = ask(p, l, mid, o << );
}
else {
A = ask(p, mid + , r, o << | );
}
int t = ans[o];
if(getY(A, p) - eps > getY(t, p)) {
t = A;
}
else if(fabs(getY(A, p) - getY(t, p)) < eps) {
t = std::min(t, A);
}
//printf("ask: %d %d %d return %d \n", p, l, r, t);
return t;
}
}SgT; int main() {
int n, MO = , lastans = , num = ;
scanf("%d", &n);
for(int i = , f, x, xx, y, yy; i <= n; i++) {
scanf("%d", &f);
if(f) {
scanf("%d%d%d%d", &x, &y, &xx, &yy);
x = (x + lastans - ) % MO + ;
xx = (xx + lastans - ) % MO + ;
y = (y + lastans - ) % + ;
yy = (yy + lastans - ) % + ;
if(x > xx) {
std::swap(x, xx);
std::swap(y, yy);
}
sg[++num].l = x;
sg[num].r = xx;
if(x == xx) {
sg[num].k = 1.0 * INF;
sg[num].b = 1.0 * std::max(y, yy);
}
else {
sg[num].k = 1.0 * (y - yy) / (x - xx);
sg[num].b = y - sg[num].k * x;
}
SgT.add(x, xx, num, , MO, );
/*for(int i = 1; i <= 11; i++) {
SgT.ask(i, 1, MO, 1);
}
puts("");*/
}
else {
scanf("%d", &x);
x = (x + lastans - ) % MO + ;
lastans = SgT.ask(x, , MO, );
printf("%d\n", lastans);
}
} /*puts("");
for(int i = 1; i <= num; i++) {
printf("%lf %lf %d %d \n", sg[i].k, sg[i].b, sg[i].l, sg[i].r);
}*/ return ;
}

AC代码

调起来真难...很不理解为什么有人的李超树代码只有我的 1 / 3 长

HEOI2013 Segment的更多相关文章

  1. bzoj 3165: [Heoi2013]Segment 动态凸壳

    3165: [Heoi2013]Segment Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 202  Solved: 89[Submit][Stat ...

  2. 【BZOJ3165】[HEOI2013]Segment(李超线段树)

    [BZOJ3165][HEOI2013]Segment(李超线段树) 题面 BZOJ 洛谷 题解 似乎还是模板题QwQ #include<iostream> #include<cst ...

  3. 洛谷 P4097 [HEOI2013]Segment 解题报告

    P4097 [HEOI2013]Segment 题目描述 要求在平面直角坐标系下维护两个操作: 在平面上加入一条线段.记第 \(i\) 条被插入的线段的标号为 \(i\) 给定一个数 \(k\),询问 ...

  4. BZOJ 3165: [Heoi2013]Segment

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

  5. Bzoj 3165 [Heoi2013]Segment题解

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

  6. BZOJ3165 : [Heoi2013]Segment

    建立线段树,每个节点维护该区间内的最优线段. 插入线段时,在线段树上分裂成$O(\log n)$棵子树,若与当前点的最优线段不相交,那么取较优的,否则暴力递归子树. 查询时在叶子到根路径上所有点的最优 ...

  7. 【题解】Luogu P4097 [HEOI2013]Segment

    原题传送门 这珂以说是李超线段树的模板题 按着题意写就行了,时间复杂度为\(O(n\log^2n)\) #include <bits/stdc++.h> #define N 40005 # ...

  8. BZOJ3165[Heoi2013]Segment——李超线段树

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

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

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

随机推荐

  1. IIS下载地址

    https://www.microsoft.com/zh-cn/download/confirmation.aspx?id=1038

  2. Linux 文件及目录管理命令基础

    pwd   显示当前所在目录 cd 切换目录 cd 命令语法 cd [选项] 目录 cd 的常用选项: cd ~ /cd 切换到当前用户的加目录 cd . 保持当前目录不变 cd .. 切换到上级目录 ...

  3. Python基础知识2-内置数据结构(下)

    bytes.bytearray #思考下面例子: a = 1 b = a print(a == b)#True print(a is b)#True print(id(a) is id(b))#Fal ...

  4. python爬虫之win7Mongod安装使用

    1.下载地址:https://www.mongodb.com/download-center#community 下载完成以后下一步下一步安装. 安装路径 还需要建立一个数据库存储位置C:\mongo ...

  5. JavaScript中forEach与each

    forEach是ES5中操作数组的一种方法,主要功能是遍历数组,例如: var arr = [1,2,3,4]; arr.forEach(alert); 等价于: var arr = [1, 2, 3 ...

  6. DAY09、函数

    一.函数的定义:跟变量名的定义大同小异 1.声明函数的关键词:def 2.函数(变量)名:使用函数的依据 3.参数列表:()   参数个数可以为0到n个,但()一定不能丢,完成功能的必要条件 4.函数 ...

  7. Mybatis之执行自定义SQL举例

    本文说明如何使用Mybatis执行我自定义输入的SQL语句. 需要的mybaits文件包括:配置文件(mybatis-config-dao.xml 和 jdbc.properties).接口文件(IS ...

  8. 转 在PowerDesigner的PDM图形窗口中显示数据列的中文注释

    Name是名称(字段描述),Code是字段名称,Comment是注释名称,ER图中显示的是Name.一般设计时,Name跟comment都设计成描述, 而设计时候常把comment写成中文,name保 ...

  9. Linux下4个查找命令which、whereis、locate、find的总结

    (1)which   [-a]    cmdname1 cmdname2 ...... 作用:locate a command,从环境变量PATH中,定位/返回与指定名字相匹配的可执行文件所在的路径 ...

  10. float数组转字符串实施方案小记

    float[] floats = {1.2f , 3.5f , 6.4f}; Double[] doubles = IntStream.range(0, floats.length).mapToDou ...