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. 常用的shell(备份数据库、备份网站、切割访问日志)

    备份网站程序 #!/bin/bash /bin/tar czf /mnt/backup_website/web_$(date +%Y%m%d_%H%M%S).gz.tar /mnt/wwwroot/w ...

  2. LINQ查询表达式---------where子句

    LINQ查询表达式---------where子句 where 子句用在查询表达式中,用于指定将在查询表达式中返回数据源中的哪些元素. 它将一个布尔条件(“谓词”)应用于每个源元素(由范围变量引用), ...

  3. 零元学Expression Blend 4 - Chapter 37 看如何使用Clip修出想要的完美曲线(上)

    原文:零元学Expression Blend 4 - Chapter 37 看如何使用Clip修出想要的完美曲线(上) 几何外部的 UIElement 会在呈现的配置中以视觉化方式裁剪. 几何不一定要 ...

  4. 零元学Expression Blend 4 - Chapter 34 啊~!!我不要毛毛的感觉!-使用布局修整「UseLayoutRounding」

    原文:零元学Expression Blend 4 - Chapter 34 啊~!!我不要毛毛的感觉!-使用布局修整「UseLayoutRounding」 本章将介绍UseLayoutRounding ...

  5. chrome 里面js提示Provisional headers are shown错误

    参考:http://stackoverflow.com/questions/21177387/caution-provisional-headers-are-shown-in-chrome-debug ...

  6. CSS3 Generator提供了13个CSS3较为常用的属性代码生成工具,而且可以通过这款工具除了在线生成效果代码之外,还可以实时看到你修改的效果,以及浏览器的兼容性。

    CSS3 Generator提供了13个CSS3较为常用的属性代码生成工具,而且可以通过这款工具除了在线生成效果代码之外,还可以实时看到你修改的效果,以及浏览器的兼容性. CSS3 Generator ...

  7. QAbstractItemView为截断的项显示ToolTip(使用事件过滤)

    在Qt中想要为QAbstractItemView中长度不够而使得内容被截断的项显示ToolTip,Qt官网有一篇文章介绍使用事件过滤器来显示太长的项,但是没有涵盖图标的情况.显示列头项太长的情况等等, ...

  8. 笨重的mfc还在基于系统控件,熟练的mfc工程师还比不过学习Qt一个月的学生开发效率高(比较精彩,韦易笑)

    作者:韦易笑链接:https://www.zhihu.com/question/29636221/answer/45102191来源:知乎著作权归作者所有,转载请联系作者获得授权. 更新:擦,本来只有 ...

  9. 《C++ Primer》读书笔记 第三章

    1.注意:头文件不应包含using声明.因为头文件的内容会拷贝到所有引用他的文件中去,对于某些程序来说,由于不经意间包含了一些名字,可能会产生名字冲突.2.string类型的读入:用cin读入stri ...

  10. CMD 从文件中截取匹配规则字符串并输出到文件

    *******************command**********************git diff 8d71d92b2d957fd1b697b4cf785fb984f190e5d2 or ...