3165: [Heoi2013]Segment

Time Limit: 40 Sec  Memory Limit: 256 MB
Submit: 668  Solved: 276
[Submit][Status][Discuss]

Description

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

Input

第一行一个整数n,表示共n 个操作。 
接下来n行,每行第一个数为0或1。 
 
若该数为 0,则后面跟着一个正整数 k,表示询问与直线  
x = ((k +lastans–1)%39989+1)相交的线段中交点(包括在端点相交的情形)最靠上的线段的编号,其中%表示取余。若某条线段为直线的一部分,则视作直线与线段交于该线段y坐标最大处。若有多条线段符合要求,输出编号最小的线段的编号。 
若该数为 1,则后面跟着四个正整数 x0, y0, x 1, y 1,表示插入一条两个端点为 
((x0+lastans-1)%39989+1,(y0+lastans-1)%10^9+1)和((x
1+lastans-1)%39989+1,(y1+lastans-1)%10^9+1) 的线段。 
其中lastans为上一次询问的答案。初始时lastans=0。

Output

对于每个 0操作,输出一行,包含一个正整数,表示交点最靠上的线段的编号。若不存在与直线相交的线段,答案为0。

Sample Input

6
1 8 5 10 8
1 6 7 2 6
0 2
0 9
1 4 7 6 7
0 5

Sample Output

2
0 3

HINT

对于100%的数据,1 ≤ n ≤ 10^5 , 1 ≤  k, x0, x1 ≤ 39989, 1 ≤ y0 ≤ y1 ≤ 10^9。

  这道题用到了李超线段树,由于不会,就上网强行看了一波题解+标程,然后一脸蒙蔽的打完了。

  首先我们可以注意到x的数据范围比y要明显小得多,那么我们可以根据x建线段树,每一个节点代表一个x值,维护的内容就是当前区间内的最靠上的线段。

  到这里可能有些人会和博主有一样的疑问,对于一个区间,他每个点的最优解可能来自多条直线,我们该怎么处理呢?这就是李超线段树强悍的地方了,对于这种情况我们不会因为到达当前要修改的位置而停止,而是接着向他的儿子们转移,这样,我们早晚可以让这条线段成为完全的最优解。

  对于询问,李超线段树也和平常线段树不一样,首先对于无斜率的线段由于只可能有一个最优解,我们不必再把它放到线段树里面,而是单独记录,然后就从上往下进行查询,查到对应的单点为止,对于我们在路上碰到的节点的最优解我们都可以对我们的答案进行更新,因为他们都覆盖了目标节点。最后直接输出即可。

 #include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cmath>
#include<map>
#define N 40005
#define M 100005
using namespace std;
int n,p1=,p2=,la;
struct no
{
int left,right,mid;
int id;
}node[N*];
struct li
{
int x1,x2,y1,y2;
}line[M];
void build(int left,int right,int x)
{
node[x].left=left,node[x].right=right;
if(left==right)
return;
int mid=(left+right)/;
node[x].mid=mid;
build(left,mid,*x);
build(mid+,right,*x+);
}
double get_k(li a)
{
return double(a.y2-a.y1)/double(a.x2-a.x1);
}
int lmax[N][],zz;
void add(int left,int right,int x,int id)
{ if(!node[x].left)return;//为了防止到了单点还继续向下更新
if(node[x].left==left&&node[x].right==right)
{
if(!node[x].id)node[x].id=id;
else
{
double k1=get_k(line[node[x].id]);
double k2=get_k(line[id]);
double y1=double(line[node[x].id].y1)-k1*double(line[node[x].id].x1)+k1*left,y2=line[node[x].id].y1-k1*double(line[node[x].id].x1)+k1*right;
double y3=double(line[id].y1)-k2*double(line[id].x1)+k2*left,y4=line[id].y1-k2*double(line[id].x1)+k2*right;
if(y1>=y3&&y2>=y4)
return;
else if(y1<=y3&y2<=y4)
node[x].id=id;
else
{
int mid=node[x].mid;
add(left,mid,x*,id);
add(mid+,right,*x+,id);
}
}
return;
}
int mid=node[x].mid;
if(left>mid)
add(left,right,*x+,id);
else if(right<=mid)
add(left,right,*x,id);
else
add(left,mid,*x,id),add(mid+,right,*x+,id);
}
int ans;
double mx;
void get(int to,int x)
{
if(node[x].id)
{
double k=get_k(line[node[x].id]);
double y=double(line[node[x].id].y1)-k*double(line[node[x].id].x1)+k*to;
if(mx<y)
{
mx=y;
ans=node[x].id;
}
}
if(node[x].left==node[x].right)return;
int mid=node[x].mid;
if(to>mid)get(to,*x+);
else get(to,*x);
}
int main()
{
memset(lmax,-0x7f,sizeof(lmax));
scanf("%d",&n);
build(,p1,);
for(int i=;i<=n;i++)
{
int t;
scanf("%d",&t);
if(t==)
{
int x1,x2,y1,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
x1=(x1+la-)%p1+,y1=(y1+la-)%p2+;
x2=(x2+la-)%p1+,y2=(y2+la-)%p2+;
zz++;
line[zz].x1=x1,line[zz].x2=x2,line[zz].y1=y1,line[zz].y2=y2;
if(x1==x2)
{
if(y1>y2) swap(y1,y2);
if(lmax[x1][]<y2) lmax[x1][]=zz,lmax[x1][]=y2;
}
else
{
if(x1>x2)swap(x1,x2);//不要忘记左右端点大小顺序
add(x1,x2,,zz);
}
}
else
{
int x;
scanf("%d",&x);
x=(x+la-)%p1+;
mx=lmax[x][];
ans=lmax[x][];
if(ans==lmax[][])ans=;
get(x,);
printf("%d\n",ans);
la=ans;
}
}
return ;
}

Bzoj 3165 [Heoi2013]Segment题解的更多相关文章

  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

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

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

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

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

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

  5. BZOJ3165 & 洛谷4097:[HEOI2013]Segment——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=3165 https://www.luogu.org/problemnew/show/P4097 要求 ...

  6. Bzoj 3166 [Heoi2013] Alo 题解

    3166: [Heoi2013]Alo Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1118  Solved: 518[Submit][Status ...

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

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

  8. BZOJ 1003 物流运输 题解 【SPFA+DP】

    BZOJ 1003 物流运输 题解 Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的 ...

  9. BZOJ 1191 超级英雄 Hero 题解

    BZOJ 1191 超级英雄 Hero 题解 Description 现在电视台有一种节目叫做超级英雄,大概的流程就是每位选手到台上回答主持人的几个问题,然后根据回答问题的多少获得不同数目的奖品或奖金 ...

随机推荐

  1. Win10中解决Prolific PL2303出现错误代码10的问题

    PL2303 是Prolific 公司生产的一种高度集成的RS232-USB接口转换器,在Win10中默认安装的驱动程序会出现错误代码10的问题,如下图所示: 下载Win10上可以用的PL2303驱动 ...

  2. Windows NT WinLogon Notify

    在NT系列Windows操作系统中,恶意软件可以通过关联Winlogon特定的事件来使自身被启动,如Lock,Logoff,Logon,Shutdown,StartScreenSaver,StartS ...

  3. delphi中使用词霸2005的动态库XdictGrb.dll实现屏幕取词

    近日来,在网上发现关于屏幕取词技术的捷径,搜索很长时间,发现实现方式以VB出现的居多,但是通过Delphi来实现的却好象没有看到,自己参考着VB的相关代码琢磨了一下通过delphi来实现的方式. 其实 ...

  4. RedHat 7.3+ORACLE 12c RAC 使用udev绑定磁盘

    在RedHat 7中,很多命令发生了改变,其中使用udev对磁盘绑定的命令也发生了变更,不再使用start_udev,而是改为了udevadm,下面具体介绍如何使用udev对磁盘进行绑定,这里对6和7 ...

  5. Delphi编写系统服务:完成端口演示

    在开发大量Socket并发服务器,完成端口加重叠I/O是迄今为止最好的一种解决方案,下面是简单的介绍:   “完成端口”模型是迄今为止最为复杂的一种I/O模型,特别适合需要同时管理为数众多的套接字,采 ...

  6. 编译icu库(用到了cygwin)

    源码下载 icu项目地址 安装cygwin,至少安装以下几个工具 make dos2unix binutils 编译工程 打开命令行,进入根目录的 source 文件夹 配置VC编译环境,执行命令 “ ...

  7. QImage的浅拷贝与深拷贝

     首先简单说说什么是浅拷贝和深拷贝:浅拷贝就比如像引用类型,而深拷贝就比如值类型,即浅拷贝是共用一块内存的,而深拷贝是复制一份内容.   我们再来看看QImage类的几个构造函数: // 浅拷贝 QI ...

  8. Spring之ApplicationContext

    (1)ApplicationContext接口容器 ApplicationContext用于加载Spring的配置文件,在程序中充当“容器”的角色.其实现类有两个.通过Ctrl +T查看: A.配置文 ...

  9. echarts 中国地图标注所在点

    达到的效果: 1.本身是个中国地图‘ 2.直接通过经纬度标注 3.标注点可以是其他样子(比如:五角星) 4.标注点具有提示框并且鼠标可以进入 5.提示框里的链接可点击(可以添加为链接事件): 所需要技 ...

  10. (Demo分享)利用JavaScript(JS)做一个可输入分钟的倒计时钟功能

    利用JavaScript(JS)实现一个可输入分钟的倒计时钟功能本文章为 Tz张无忌 原创文章,转载请注明来源,谢谢合作! 网络各种利用JavaScript做倒计时的Demo对新手很不友好,这里我亲手 ...