题意:

给出平面上一些线段,在线询问与x=x0相交的线段中,交点y最大的线段的标号,支持添加线段。

大概思路:

用线段树维护,线段树每个线段记录贯穿(左右端点在该区间外或上)的原线段中能覆盖其它贯穿该线段的原线段(即每个线段树线段记录贯穿该线段的所有原线段中“最高”的)

细节:

添加原线段s到线段树线段nd:

如果s不能覆盖,根据s的大小传递到左儿子或右儿子或都传

如果s覆盖,

如果原本没有线段,则直接设置为s

   如果有线段ss,求s与ss的交点,将短(比较x上投影的长度)的线段“压”到交点所在儿子,长的变成本区间的。

  (要注意如果y相等,比较标号)

查询x

  查询覆盖x的所有区间的线段树线段对应的原线段(有的话)中在x处y最大的。

 /**************************************************************
Problem: 3165
User: idy002
Language: C++
Result: Accepted
Time:1492 ms
Memory:4244 kb
****************************************************************/ #include <cstdio>
#include <cmath>
#include <vector>
#define lson nd<<1
#define rson nd<<1|1
#define maxn 100010
#define modx 39989
#define mody 1000000000
#define eps 1e-10
using namespace std; int sg( double x ) {
return (x>-eps)-(x<eps);
}
struct Line {
int lf, rg;
double k, b;
Line(){}
Line( int x0, int y0, int x1, int y1 ) {
lf = min( x0, x1 );
rg = max( x0, x1 );
if( x0==x1 ) {
k = 0.0;
b = max( y0, y1 );
} else {
k = (y1-y0+0.0)/(x1-x0);
b = y1-x1*k;
}
}
inline double f( int x ) {
return k*x+b;
}
inline double cx( Line &c ) {
return (c.b-b)/(k-c.k);
}
}; int n;
int ltot;
Line lns[maxn];
int v[(modx+)<<];
int wi[modx+];
double wy[modx+]; void update( int x, int i ) {
double ny = lns[i].f(x);
int s=sg(ny-wy[x]);
if( !wi[x] || (s> || (s==&&i<wi[x])) ) {
wi[x] = i;
wy[x] = ny;
}
}
void modify( int i, int nd, int lf, int rg ) {
if( lns[i].lf<=lf && rg<=lns[i].rg ) {
if( !v[nd] ) {
v[nd] = i;
return;
}
bool lu = sg( lns[i].f(lf)-lns[v[nd]].f(lf) )>;
bool ru = sg( lns[i].f(rg)-lns[v[nd]].f(rg) )>;
int mid=(lf+rg)>>;
if( lu && ru ) {
v[nd] = i;
} else if( lu || ru ) {
int lm = floor( lns[i].cx( lns[v[nd]] ) );
if( lm<=mid && lu ) {
modify( i, lson, lf, mid );
} else if( lm<=mid && ru ) {
modify( v[nd], lson, lf, mid );
v[nd] = i;
} else if( lu ) {
modify( v[nd], rson, mid+, rg );
v[nd] = i;
} else {
modify( i, rson, mid+, rg );
}
} else {
update( lf, i );
update( rg, i );
}
return;
}
int mid = (lf+rg)>>;
if( lns[i].lf<=mid ) modify( i, lson, lf, mid );
if( lns[i].rg>mid ) modify( i, rson, mid+, rg );
}
int query( int x ) {
int nd = ;
int lf = , rg = modx;
int rt = ;
double cury = -1.0;
while() {
if( v[nd] ) {
double ny = lns[v[nd]].f(x);
int s = sg( ny-cury );
if( s> || (s==&&v[nd]<rt) ) {
rt = v[nd];
cury = ny;
}
}
if( lf==rg ) break;
int mid=(lf+rg)>>;
if( x<=mid ) {
nd = lson;
rg=mid;
} else {
nd = rson;
lf=mid+;
}
}
int s = sg( wy[x]-cury );
if( s> || (s==&&wi[x]<rt) )
return wi[x];
return rt;
} int main() {
int T, lastans=;
scanf( "%d", &T );
while( T-- ) {
int opt;
scanf( "%d", &opt );
if( opt== ) {
int x;
scanf( "%d", &x );
x = ((x+lastans-)%modx+);
printf( "%d\n", lastans=query(x) );
} else {
int x0, y0, x1, y1;
scanf( "%d%d%d%d", &x0, &y0, &x1, &y1 );
x0 = (x0+lastans-)%modx+;
y0 = (y0+lastans-)%mody+;
x1 = (x1+lastans-)%modx+;
y1 = (y1+lastans-)%mody+;
lns[++ltot] = Line(x0,y0,x1,y1);
modify( ltot, , , modx );
}
}
}

bzoj 3165的更多相关文章

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

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

  2. BZOJ.3165.[HEOI2013]Segment(李超线段树)

    BZOJ 洛谷 对于线段,依旧是存斜率即可. 表示精度误差一点都不需要管啊/托腮 就我一个人看成了mod(10^9+1)吗.. //4248kb 892ms #include <cstdio&g ...

  3. BZOJ 3165: [Heoi2013]Segment

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

  4. Bzoj 3165 [Heoi2013]Segment题解

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

  5. 【BZOJ 3165】【HEOI 2013】Segment

    往区间上覆盖一次函数,做法是用线段树维护标记永久化. 每次都忘了线段树要4倍空间,第一次交总是RE,再这么手残的话考场上就真的要犯逗了. #include<cstdio> #include ...

  6. BZOJ 3165 Segment

    同上题. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm&g ...

  7. 【BZOJ 3165】 [Heoi2013]Segment 李超线段树

    所谓李超线段树就是解决此题一类的问题(线段覆盖查询点最大(小)),把原本计算几何的题目变成了简单的线段树,巧妙地结合了线段树的标记永久化与标记下传,在不考虑精度误差的影响下,打法应该是这样的. #in ...

  8. bzoj 3165: [Heoi2013]Segment 线段树

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

  9. BZOJ 3165 李超线段树

    思路: 李超线段树 我是把线段转成斜率的形式搞得 不知道有没有更简单的方法 //By SiriusRen #include <cmath> #include <cstdio> ...

随机推荐

  1. shell中$*与$@的区别

    $*所有的位置参数,被作为一个单词 注意:"$*"必须被""引用 $@ 与$*同义,但是每个参数都是一个独立的""引用字串,这就意味着参数被 ...

  2. python基础===利用unittest进行测试用例执行的几种方式

    利用python进行测试时,测试用例的加载方式有2种:  一种是通过unittest.main()来启动所需测试的测试模块:  一种是添加到testsuite集合中再加载所有的被测试对象,而tests ...

  3. shell source命令说明

    当我修改了/etc/profile文件,我想让它立刻生效,而不用重新登录:这时就想到用source命令,如:source /etc/profile对source进行了学习,并且用它与sh 执行脚本进行 ...

  4. Linux-Load Average解析(转)

    load Average 1.1:什么是Load?什么是Load Average?   Load 就是对计算机干活多少的度量(WikiPedia:the system Load is a measur ...

  5. 教你如何修改FireFox打开新标签页(NewTab Page)的行列数

    FireFox的打开新建标签页(即NewTab Page)默认只能显示3x3个网站缩略图,这9个自定义的网站,非常方便快捷,什么hao123的弱爆了,本人从未用过此类导航网站,曾经用过的也只是abou ...

  6. C/C++——[04] 语句

    在 C/C++语言中,语句以“ :”结束.某些情况下,一组语句在一起共同完成某一特定的功能,可以将它们用大括号括起来.我们称之为语句组.语句组可以出现在任何单个语句出现的地方. 1. 分支语句 一般情 ...

  7. 提高spring boot jpa性能(译)

    Spring Data JPA为Spring应用程序提供了数据访问层的实现.这是一个非常方便的组件,因为它不会重新发明每个新应用程序的数据访问方式,因此您可以花更多时间来实现业务逻辑.使用Spring ...

  8. objective-c Quick Reference

  9. [实战]MVC5+EF6+MySql企业网盘实战(5)——页面模板

    写在前面 上篇文章更新了网盘的登录界面,以及用户头像的等比例压缩功能.今天折腾一下页面的样式,将从网上找的一个模板套用在项目中. 系列文章 [EF]vs15+ef6+mysql code first方 ...

  10. 【LOJ】#2017. 「SCOI2016」围棋

    题解 考虑到状态数比较复杂,其实我们需要轮廓线dp-- 我们设置\(f[x][y][S][h][k]\)为考虑到第(x,y)个格子,S是轮廓线上的匹配状态,是二进制,如果一位是1表示这一位匹配第一行匹 ...