博客:http://www.cnblogs.com/mangoyang/p/9979465.html

李超线段树支持两种操作:1:插入一条直线。2:询问在x = c与这些直线的交点中最大的y坐标。

插入的时候,如果有交点,本层节点留下来的是优势直线,劣势的那条去递归比较。优势直线是指在这个区间中覆盖的面积最大的那条直线。

维护的时候用了标记永久化,所以递归询问回溯的时候比较所有的直线,取坐标最大的那一条。

复杂度O(n(lgn)^2),常数相对于平衡树比较小。

代码:

#include <bits/stdc++.h>
#define ls(x) (x << 1)
#define rs(x) ((x << 1) | 1)
using namespace std;
const int maxn = 100010;
struct line {
double k, b;
};
line a[maxn];
int tot;
struct SegementTree {
int id;
};
SegementTree tr[maxn * 4];
double get_pos(int x, int y) {
return a[x].k * y + a[x].b;
}
double cross(int x, int y) {
return (a[x].b - a[y].b) / (a[y].k - a[x].k);
}
void update(int o, int l, int r, int now) {
if(!tr[o].id) {
tr[o].id = now;
return;
}
int x = tr[o].id;
double l1 = get_pos(now, l), r1 = get_pos(now, r);
double l2 = get_pos(x, l), r2 = get_pos(x, r);
if(l1 <= l2 && r1 <= r2) {
return;
}
else if(l1 > l2 && r1 > r2) {
tr[o].id = now;
return;
}
int mid = (l + r) >> 1;
double y = cross(now, x);
if(y <= mid) update(ls(o), l, mid, r1 > r2 ? x : now);
else update(rs(o), mid + 1, r, l1 > l2 ? x : now);
if((y <= mid && r1 > r2) || (y > mid && l1 > l2))
tr[o].id = now;
}
int query(int o, int l, int r, int pos) {
if(l == r) {
return tr[o].id;
}
int mid = (l + r) >> 1, ans = 0;
if(pos <= mid) ans = query(ls(o), l, mid, pos);
else ans = query(rs(o), mid + 1, r, pos);
if(!tr[o].id) return ans;
int x = tr[o].id;
if(get_pos(x, pos) > get_pos(ans, pos)) return x;
else return ans;
}
char s[110];
int main() {
int n;
double x, y;
int z;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%s",s + 1);
if(s[1] == 'P') {
scanf("%lf%lf", &x, &y);
a[++tot] = (line){y, x};
update(1, 0, 50000, tot);
} else {
scanf("%d", &z);
int ans = query(1, 0, 50000, z - 1);
printf("%d\n", (int)(get_pos(ans, z - 1) / 100));
}
}
}

  

最新文章

  1. [LeetCode] Regular Expression Matching 正则表达式匹配
  2. 介绍两个Ubuntu上的桌面小工具
  3. 基于opencv和mfc的摄像头采集代码(GOMFCTemplate2)
  4. 实用的开放源码的Excel导入导出类库 CarlosAg ExcelXmlWriter
  5. 【学】SoapExtension 学习
  6. 大型web系统架构详解
  7. windows7开启虚拟wifi和虚拟无线AP的方法
  8. 利用Linux系统函数alarm() 来检测计算机性能
  9. IE6滤镜在实战测试中能让父层里面的子元素产生阴影
  10. 安装Android的SDK
  11. JDBC 查询
  12. Mybatis第一天
  13. python的可变对象与不可变对象
  14. 10.vue框架
  15. mui框架下监听返回按钮
  16. Hibernate_day01
  17. 知识点查缺补漏贴01-进程间通讯之mmap文件共享
  18. drbd + pacemaker
  19. Unity 代码控制游戏对象是父物体的第多少个子对象
  20. jenkins~管道Pipeline里使用公用类库

热门文章

  1. 机器学习(三)—线性回归、逻辑回归、Softmax回归 的区别
  2. 使用Spring MVC表单标(转)
  3. H5实现登录
  4. Mat ,IplImage, CvMat 之间的转换的总结
  5. main函数的参数的用法
  6. UVALive - 4126 Password Suspects (AC自动机+状压dp)
  7. 2016 ACM-ICPC EC-Final题解
  8. 洛谷【P1714】切蛋糕
  9. Log4net系统日志
  10. JDK7和JDK8新特性