题目描述

“我是超级大沙茶”——Mato_No1
为了证明自己是一个超级大沙茶,Mato 神犇决定展示自己对叉(十字型)有多么的了
解。
Mato 神犇有一个平面直角坐标系,上面有一些线段,保证这些线段至少与一条坐标轴
平行。Mato 神犇需要指出,这些线段构成的最大的十字型有多大。
称一个图形为大小为 R(R 为正整数)的十字型,当且仅当,这个图形具有一个中心点,
它存在于某一条线段上,并且由该点向上下左右延伸出的长度为 R 的线段都被已有的线段
覆盖。
你可以假定:没有两条共线的线段具有公共点,没有重合的线段。

输入

第一行,一个正整数 N,代表线段的数目。
以下 N 行,每行四个整数 x1,y1,x2,y2(x1=x2 或 y1=y2) ,描述了一条线段。

输出

当不存在十字型时:输出一行“Human intelligence is really terrible” (不包括引号) 。
否则:输出一行,一个整数,为最大的 R。

样例输入

1
 
0 0 0 1

样例输出

Human intelligence is really terrible

提示

【样例输入 2】
3
-1 0 5 0
0 -1 0 1
2 -2 2 2
【样例输出 2】
2
【样例输入输出 3】
见附加文件 cross.in/ans。
【数据规模与约定】
对于 50%的数据:N≤1000。
对于 100%的数据:1≤N≤100000,所有坐标的范围在-10^9~10^9 中。
后 50%内,所有数据均为随机生成。
 

题解

这道题可以暴力水过,正解是二分+扫描线+平衡树

网上看到的题解都是暴力的,这里写一下正解的算法

读入的时候我们先把横的和竖的线都找出来,并且存一下每条线的len和两端的位置(如果是横的就记录x1,x2,竖的就记录y1,y2)

然后我们二分答案,每次check的时候,把所有线段都减去2*二分的长度(因为两边都要减)并加到新数组里(横的归横的,竖的归竖的),这里我们还要多加一个id值,在之后能用到,如果某条线段的长度不够了,就不用把这条线加到数组里面了

这里我用th[]记录横的线,ts[]记录竖的线

加到数组中后,我们就开始扫描,扫描到横的线的左端就把这条线的y坐标加入到平衡树上(可以用c++的set),扫描到竖的线就查找lower_bound(这条线的下端点),判断一下找到的值是否<=这条线的上端点,如果扫到横的线的右端就把这条线的y坐标从平衡树上删去

因为坐标的范围很大,我们不能直接枚举坐标,所以我们可以按横的线的左端和右端分别排个序,用L[]和R[]存一下,每次用指针往后找就可以了,至于多加的id值,因为排过序,横的线的次序就打乱了,所以我们在加入到数组后直接用另一个数组把th[]存下来,这样每次查询id的时候就可以找到原来的th[].id了

说了那么多,来看看代码吧(可能会好懂一些)

 #include<algorithm>
#include<cstdio>
#include<cstring>
#include<set>
#define N 100005
using namespace std;
int n,x1,x2,y1,y2,cnt1,cnt2,l,r,ans,nums,numh;
multiset<int> q;
typedef set<int>::iterator It;
struct node{
int x,l,r,len;
}s[N],ts[N];
struct Node{
int y,l,r,len,id;
}h[N],th[N],Th[N];
struct NODE{
int p,id;
}L[N],R[N];
bool cmp(node x,node y){ return x.x<y.x; }
bool cmp1(Node x,Node y){
if (x.l!=y.l) return x.l<y.l;
else return x.r<y.r;
}
bool cmp2(Node x,Node y){
if (x.r!=y.r) return x.r<y.r;
else return x.l<y.l;
}
void pre(int len){
nums=numh=;
for (int i=;i<=cnt1;i++)
if (s[i].len>=*len){
ts[++nums].x=s[i].x;
ts[nums].len=s[i].len-*len;
ts[nums].l=s[i].l+len; ts[nums].r=s[i].r-len;
}
for (int i=;i<=cnt2;i++)
if (h[i].len>=*len){
th[++numh].y=h[i].y;
th[numh].len=h[i].len-*len;
th[numh].l=h[i].l+len; th[numh].r=h[i].r-len;
th[numh].id=numh;//加入的id值
}
memcpy(Th,th,sizeof(th));//用临时数组把th存下来,因为之后th数组会被排序
}
bool check(int len){
q.clear();
q.insert(1e9);//防止lower_bound找到0
pre(len);
sort(ts+,ts++nums,cmp);
sort(th+,th++numh,cmp1);
for (int i=;i<=numh;i++)
L[i].p=th[i].l,L[i].id=th[i].id;//按左端点排序
sort(th+,th++numh,cmp2);
for (int i=;i<=numh;i++)
R[i].p=th[i].r,R[i].id=th[i].id;//按右端点排序
L[numh+].p=R[numh+].p=ts[nums+].x=1e9;//防止越界
int x=,y=,z=;
while (x<=numh||y<=numh||z<=nums){
int a=,b=,c=;
if (L[x+a].p<=R[y].p&&L[x+a].p<=ts[z].x){
q.insert(Th[L[x].id].y);
a++;
while (L[x+a-].p==L[x+a].p) q.insert(Th[L[x+a].id].y),a++;//把相同左端点的都加到set中
}
if (ts[z+c].x<=L[x].p&&ts[z+c].x<=R[y].p){
It s=q.lower_bound(ts[z].l);
if (*s<=ts[z].r) return true;
c++;
while (ts[z+c-].x==ts[z+c].x){//查询,意义同上面
It s=q.lower_bound(ts[z+c].l);
if (*s<=ts[z+c].r) return true;
c++;
}
}
if (R[y].p<=L[x].p&&R[y].p<=ts[z].x){
q.erase(Th[R[y].id].y);
b++;
while (R[y+b-].p==R[y+b].p) q.erase(Th[R[y+b].id].y),b++;//删除,意义同上
}
x+=a; y+=b; z+=c;//不能直接把指针向后移
}
return false;
}
int main(){
scanf("%d",&n);
for (int i=;i<=n;i++){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if (x1>x2) swap(x1,x2);
if (y1>y2) swap(y1,y2);
if (x1==x2){
s[++cnt1].x=x1; s[cnt1].l=y1; s[cnt1].r=y2; s[cnt1].len=y2-y1;
} else{
h[++cnt2].y=y1; h[cnt2].l=x1; h[cnt2].r=x2; h[cnt2].len=x2-x1;
}
}
l=; r=1e9; ans=1e9;
while (l<=r){
int mid=(l+r)>>;
if (check(mid)){
ans=mid; l=mid+;
} else r=mid-;
}
if (ans!=1e9) printf("%d\n",ans);
else puts("Human intelligence is really terrible");
return ;
}

YYHS-Super Big Stupid Cross(二分+扫描线+平衡树)的更多相关文章

  1. BZOJ.4009.[HNOI2015]接水果(整体二分 扫描线)

    LOJ BZOJ 洛谷 又是一个三OJ rank1!=w= \(Description\) (还是感觉,为啥非要出那种题目背景啊=-=直接说不好么) 给定一棵树和一个路径集合(每条路径有一个权值).\ ...

  2. 【BZOJ4009】[HNOI2015]接水果 DFS序+整体二分+扫描线+树状数组

    [BZOJ4009][HNOI2015]接水果 Description 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果.由于她已经DT FC 了The big black, ...

  3. BZOJ 4009: [HNOI2015]接水果 (整体二分+扫描线 树状数组)

    整体二分+扫描线 树状数组 具体做法看这里a CODE #include <cctype> #include <cstdio> #include <cstring> ...

  4. 【BZOJ3958】[WF2011]Mummy Madness 二分+扫描线+线段树

    [BZOJ3958][WF2011]Mummy Madness Description 在2011年ACM-ICPC World Finals上的一次游览中,你碰到了一个埃及古墓. 不幸的是,你打开了 ...

  5. [bzoj4009] [HNOI2015]接水果 整体二分+扫描线+dfs序+树状数组

    Description 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果. 由于她已经DT FC 了The big black, 她觉得这个游戏太简单了,于是发明了一个更 加 ...

  6. 【BZOJ 3958】 3958: [WF2011]Mummy Madness (二分+扫描线、线段树)

    3958: [WF2011]Mummy Madness Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 96  Solved: 41 Descripti ...

  7. 接水果(fruit)——整体二分+扫描线

    题目 [题目描述] 风见幽香非常喜欢玩一个叫做 osu! 的游戏,其中她最喜欢玩的模式就是接水果.由于她已经 DT FC 了 The big black,她觉得这个游戏太简单了,于是发明了一个更加难的 ...

  8. HDU-4417 Super Mario,划分树+二分!

    Super Mario 这个题也做了一天,思路是很清晰,不过二分那里写残了,然后又是无限RE.. 题意:就是查询区间不大于k的数的个数. 思路:裸划分树+二分答案.将区间长度作为二分范围.这个是重点. ...

  9. HDU 4747 Mex【线段树上二分+扫描线】

    [题意概述] 一个区间的Mex为这个区间没有出现过的最小自然数,现在给你一个序列,要求求出所有区间的Mex的和. [题解] 扫描线+线段树. 我们在线段树上维护从当前左端点开始的前缀Mex,显然从左到 ...

随机推荐

  1. C# checked和unchecked详解

    1.对基元类型执行的许多算术运算都可能造成溢出,有如下代码: Byte b=100; b=(Byte)(b+200); 简单的解读上面的代码: 第一步,将所有的操作数都扩大至32位或者64位(根据操作 ...

  2. Java 类的热替换 —— 概念、设计与实现

    详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp71   Java 类的热替换 -- 概念.设计与实现 构建基于 Java ...

  3. 第1阶段——uboot分析之硬件初始化start_armboot函数(5)

    start_armboot()分析:在start.S初始化后跳转到start_armboot实现第2阶段硬件相关的初始化(烧写擦除flash,网卡驱动,usb驱动,串口驱动,从FLASH读内核,启动内 ...

  4. NHibernate教程(21)——二级缓存(下)

    本节内容 引入 使用NHibernate二级缓存 启用缓存查询 管理NHibernate二级缓存 结语 引入 这篇我还继续上一篇的话题聊聊NHibernate二级缓存剩下的内容,比如你修改.删除数据时 ...

  5. webservice Dome--一个webservice的简单小实例

    1.理解:webservice就是为了实现不同服务器上不同应用程序的之间的通讯 2.让我们一步一步的来做一个webservice的简单应用 1)新建一个空的web应用程序,在程序上右键,新建项目,选择 ...

  6. 201521123084 《Java程序设计》第7周学习总结

    第7周-集合 1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 参考资料: XMind ------------------------------------------- ...

  7. Beta版本冲刺前期计划及安排

    a. 介绍小组新加入的成员,Ta担任的角色. 吴东益:经讨论决定,Ta担任角色为开发人员 李志霖:在原先的团队中负责前端开发与界面设计.现经讨论决定,Ta此次担任角色为开发人员 由他们替代原来成员陈雄 ...

  8. 团队作业4——第一次项目冲刺(ALpha版本)第四天

    一.Daily Scrum Meeting照片 二.燃尽图 三.项目进展 1.界面 完善了昨天的的代码---前端的HTML页面设计 2.功能 完成后台数据处理的全部基本功能: a.数据结构设计及数据交 ...

  9. 201521123052 《Java程序设计》 第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1.互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) ...

  10. 聊聊React高阶组件(Higher-Order Components)

    使用 react已经有不短的时间了,最近看到关于 react高阶组件的一篇文章,看了之后顿时眼前一亮,对于我这种还在新手村晃荡.一切朝着打怪升级看齐的小喽啰来说,像这种难度不是太高同时门槛也不是那么低 ...