HEOI2013 Segment
传说中的“李超树”。
大意:给你若干线段,试求横坐标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的更多相关文章
- bzoj 3165: [Heoi2013]Segment 动态凸壳
3165: [Heoi2013]Segment Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 202 Solved: 89[Submit][Stat ...
- 【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
3165: [Heoi2013]Segment Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 465 Solved: 187[Submit][Sta ...
- Bzoj 3165 [Heoi2013]Segment题解
3165: [Heoi2013]Segment Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 668 Solved: 276[Submit][Sta ...
- BZOJ3165 : [Heoi2013]Segment
建立线段树,每个节点维护该区间内的最优线段. 插入线段时,在线段树上分裂成$O(\log n)$棵子树,若与当前点的最优线段不相交,那么取较优的,否则暴力递归子树. 查询时在叶子到根路径上所有点的最优 ...
- 【题解】Luogu P4097 [HEOI2013]Segment
原题传送门 这珂以说是李超线段树的模板题 按着题意写就行了,时间复杂度为\(O(n\log^2n)\) #include <bits/stdc++.h> #define N 40005 # ...
- BZOJ3165[Heoi2013]Segment——李超线段树
题目描述 要求在平面直角坐标系下维护两个操作: 1.在平面上加入一条线段.记第i条被插入的线段的标号为i. 2.给定一个数k,询问与直线 x = k相交的线段中,交点最靠上的线段的编号. 输入 第一行 ...
- Luogu P4097 [HEOI2013]Segment 李超线段树
题目链接 \(Click\) \(Here\) 李超线段树的模板.但是因为我实在太\(Naive\)了,想象不到实现方法. 看代码就能懂的东西,放在这里用于复习. #include <bits/ ...
随机推荐
- 二叉搜索树的第k个节点
给定一棵二叉搜索树,请找出其中的第k小的结点.例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4. = =一看就想到中序遍历 public class Soluti ...
- Vue 鼠标移入移出事件
Vue 中鼠标移入移出事件 @mouseover和@mouseleave 然后绑定style 现在开始代码示例 <template> <div class="pc&qu ...
- mapreduce join
MapReduce Join 对两份数据data1和data2进行关键词连接是一个很通用的问题,如果数据量比较小,可以在内存中完成连接. 如果数据量比较大,在内存进行连接操会发生OOM.mapredu ...
- Python turtle绘制阴阳太极图代码解析
本文详细分析如何使用Python turtle绘制阴阳太极图,先来分解这个图形,图片中有四种颜色,每条曲线上的箭头表示乌龟移动的方向,首先从中心画一个半圆(红线),以红线所示圆的直径作半径画一个校园, ...
- css & clearfix & clear-fixed
css & clearfix & clear-fixed https://zzk.cnblogs.com/my/s/blogpost-p?Keywords=clearfix .grou ...
- timestamp 与 nonce 防止重放攻击
重放攻击是计算机世界黑客常用的攻击方式之一,所谓重放攻击就是攻击者发送一个目的主机已接收过的包,来达到欺骗系统的目的,主要用于身份认证过程. 首先要明确一个事情,重放攻击是二次请求,黑客通过抓包获取到 ...
- nginx worker_processes 配置
搜索到原作者的话:As a general rule you need the only worker with large number ofworker_connections, say 10,0 ...
- 获取DataSet中某行某列的数据
LabelText = DataSet11.Tables("COMM.USERS").Rows[0]["User_Name"].tostring() Label ...
- linux mysql -- ERROR! The server quit without updating PID file (/usr/local/mysql/data/localhost.localdomain.pid)
转载 http://blog.csdn.net/caiyaodeng/article/details/45937183 linux 链接mysql 报错 ERROR! The server quit ...
- 提交已经注入文件的表单给后台上传图片 使用ajaxsubmit