P3438 [POI2006]ZAB-Frogs

给出一个不一样的解法。不需要用到斜率优化等高级算法。

下文记 \(n=w_x,m=w_y\)。


首先,答案显然满足可二分性,因此二分答案 \(d\in [0,nm]\) 确定距离的平方。

这样我们将题目转化为:求起点到终点之间是否有一条路径使得任何一个点都不被圆心是整点且半径相同的若干个圆所覆盖。记 \(r=\sqrt d\)。如果处理出一个点是否被覆盖,那么可以 \(\mathcal{O}(nm)\) BFS 求出答案。

枚举每一竖列即 \(x\),显然覆盖到该列的圆的圆心 \(x_i\) 坐标满足 \((x_i-x)^2\leq d\) 即 \(x_i-r\leq x\leq x_i+r\)。将所有圆按照 \(x_i\) 从小到大排序,Two-pointers 维护即可。

如果直接考虑一个点被覆盖的圆会很难做。不妨转换思路,枚举能够覆盖这一竖列的所有圆,记圆心为 \((x_i,y_i)\ (x_i-r\leq x\leq x_i+r)\)。显然,它能覆盖到的第 \(x\) 列的所有点的纵坐标 \(y\) 形成了一段区间。差分计算线段覆盖即可。

当然这么做显然是过不去的,因为一共有 \(m\) 列,而枚举到的圆的个数为 \(\mathcal{O}(nm)\)。因此时间复杂度为 \(nm^2\log(nm)\)。


考虑优化上面的算法。注意到在枚举所有圆时,如果出现两个圆 \((x_1,y_1)\) 和 \((x_2,y_2)\) 满足 \(y_1=y_2\) 且 \(|x_1-x|>|x_2-x|\),那么我们根本不需要考虑第一个圆 \((x_1,y_1)\),因为它能覆盖到的第 \(x\) 列的所有点包含于 \((x_2,y_2)\) 能覆盖到的第 \(x\) 列的所有点。这是很显然的,因为前者的 \(y\) 需要满足 \(|y-y_1|\leq \sqrt {d-(x_1-x)^2}\),后者的 \(y\) 需要满足 \(|y-y_2|\leq \sqrt {d-(x_2-x)^2}\),而 \(\sqrt {d-(x_1-x)^2}<\sqrt {d-(x_2-x)^2}\)。

因此,对于每一行 \(y\),维护圆心纵坐标为 \(y\) 且与当前 \(x\) 距离最小的圆,那么最终我们只需枚举 \(\mathcal{O}(n)\) 个圆即可。具体地,维护 \(n\) 个存横坐标 \(x_i\) 的队列,在 Two-pointers 添加或删除一个圆 \((x_i,y_i)\) 时,对第 \(y_i\) 个队列进行添加或删除操作即可。此外,移动到下一列 \(x\gets x+1\) 时,不断弹出每个队的队首元素直至队列只剩下一个元素或队列队首横坐标与 \(x+1\) 的距离小于队首下一个横坐标与 \(x+1\) 的距离。

时间复杂度为 \(\mathcal{O}(nm\log (nm))\)。

#include <bits/stdc++.h>
using namespace std; #define gc getchar()
#define pii pair <int,int>
#define fi first
#define se second
#define mem(x,v) memset(x,v,sizeof(x)) inline int read(){
int x=0,sign=0; char s=gc;
while(!isdigit(s))sign|=s=='-',s=gc;
while(isdigit(s))x=(x<<1)+(x<<3)+(s-'0'),s=gc;
return sign?-x:x;
} const int N=1e3+5; int n,m,leg[N][N];
int stx,sty,edx,edy,num;
struct point{
int x,y;
}p[N*N],mp[N][N]; bool vis[N][N];
pii q[N*N];
bool bfs(){
if(vis[stx][sty]==1)return 0;
int h=1,tl=0; q[++tl]={stx,sty},vis[stx][sty]=1;
while(h<=tl){
int x=q[h].fi,y=q[h++].se;
if(x==edx&&y==edy)return 1;
if(!vis[x+1][y])vis[x+1][y]=1,q[++tl]={x+1,y};
if(!vis[x-1][y])vis[x-1][y]=1,q[++tl]={x-1,y};
if(!vis[x][y+1])vis[x][y+1]=1,q[++tl]={x,y+1};
if(!vis[x][y-1])vis[x][y-1]=1,q[++tl]={x,y-1};
} return 0;
} int dist(int a,int b,int c,int d){return (a-c)*(a-c)+(b-d)*(b-d);} int d[N][N],hd[N],len[N],s[N];
void add(point x){d[x.y][len[x.y]++]=x.x;}
void del(point x){if(d[x.y][hd[x.y]]==x.x)hd[x.y]++;}
void update(int y,int x){while(d[y][hd[y]+1]&&abs(d[y][hd[y]]-x)>=abs(d[y][hd[y]+1]-x))hd[y]++;} bool check(int x){
int dis=sqrt(x);
mem(vis,0),mem(d,0),mem(hd,0),mem(len,0);
for(int i=0;i<=max(n,m);i++)vis[0][i]=vis[i][0]=vis[n+1][i]=vis[i][m+1]=1;
for(int i=1,l=1,r=1;i<=n;i++,mem(s,0)){
while(r<=num&&i+dis>=p[r].x)add(p[r++]);
while(l<=num&&i-dis>p[l].x)del(p[l++]);
for(int j=1;j<=m;j++){
update(j,i); int xx=d[j][hd[j]];
if(!xx)continue;
int radius=sqrt(x-(xx-i)*(xx-i)),l=j-radius,r=j+radius+1;
s[max(1,l)]++,s[min(m+1,r)]--;
} for(int j=1;j<=m;j++)vis[i][j]=(s[j]+=s[j-1])>0;
} return bfs();
} int main(){
cin>>n>>m>>stx>>sty>>edx>>edy>>num;
for(int i=1;i<=num;i++)p[i].x=read(),p[i].y=read(),mp[p[i].x][p[i].y]=p[i];
for(int i=1,cnt=0;i<=n;i++)for(int j=1;j<=m;j++)if(mp[i][j].x!=0)p[++cnt]=mp[i][j];
int l=-1,r=2e6;
while(l<r){
int m=(l+r>>1)+1;
check(m)?l=m:r=m-1;
} cout<<l+1<<endl;
return 0;
}

P3438 [POI2006]ZAB-Frogs的更多相关文章

  1. 洛谷 P3438 - [POI2006]ZAB-Frogs(乱搞/李超线段树)

    题面传送门 首先一眼二分答案,我们假设距离 \((i,j)\) 最近的 scarefrog 离它的距离为 \(mn_{i,j}\),那么当我们二分到 \(mid\) 时我们显然只能经过 \(mn_{i ...

  2. 分布式系统理论进阶 - Raft、Zab

    引言 <分布式系统理论进阶 - Paxos>介绍了一致性协议Paxos,今天我们来学习另外两个常见的一致性协议——Raft和Zab.通过与Paxos对比,了解Raft和Zab的核心思想.加 ...

  3. paxos(chubby) vs zab(Zookeeper)

    参考: Zookeeper的一致性协议:Zab Chubby&Zookeeper原理及在分布式环境中的应用 Paxos vs. Viewstamped Replication vs. Zab ...

  4. ZooKeeper之ZAB协议

    ZooKeeper为高可用的一致性协调框架,自然的ZooKeeper也有着一致性算法的实现,ZooKeeper使用的是ZAB协议作为数据一致性的算法,ZAB(ZooKeeper Atomic Broa ...

  5. POJ 1659 Frogs' Neighborhood(Havel-Hakimi定理)

    题目链接: 传送门 Frogs' Neighborhood Time Limit: 5000MS     Memory Limit: 10000K Description 未名湖附近共有N个大小湖泊L ...

  6. CF# Educational Codeforces Round 3 F. Frogs and mosquitoes

    F. Frogs and mosquitoes time limit per test 2 seconds memory limit per test 512 megabytes input stan ...

  7. 第三章 深入 ZAB 协议

    上一节介绍了ZAB协议的内容,本节将从系统模型.问题描述.算法描述和运行分析四方面来深入了解 ZAB 协议. 系统模型 在一个由一组进程 n ={P1,P2,...Pn}组成的分布式系统中,每一个进程 ...

  8. 第二章 ZAB协议介绍

    ZAB ( ZooKeeper Atomic Broadcast , ZooKeeper 原子消息广播协议)是zookeeper数据一致性的核心算法. ZAB 协议并不像 Paxos 算法那样,是一种 ...

  9. 【BZOJ】【1520】【POI2006】Szk-Schools

    网络流/费用流 比较裸的一道题 依旧是二分图模型,由源点S连向每个学校 i (1,0),「注意是连向第 i 所学校,不是连向学校的标号m[i]……唉这里WA了一次」 然后对于每所学校 i 连接 j+n ...

随机推荐

  1. [对对子队]Scrum Meeting 博客汇总

    对对子队 博客目录 一.Scrum Meeting 1. Alpha Scrum Meeting 1(会议记录4.10) Scrum Meeting 2(会议记录4.11) Scrum Meeting ...

  2. Spring Authorization Server的使用

    Spring Authorization Server的使用 一.背景 二.前置知识 三.需求 四.核心代码编写 1.引入授权服务器依赖 2.创建授权服务器用户 3.创建授权服务器和客户端 五.测试 ...

  3. 2021.10.7考试总结[NOIP模拟71]

    信心赛,但炸了.T3SB错直接炸飞,T4可以硬算的组合数非要分段打表求阶乘..T2也因为一个细节浪费了大量时间.. 会做难题很好,但首先还是要先把能拿的分都拿到. T1 签到题 结论:总可以做到对每个 ...

  4. STM32 学习笔记之中断应用概览--以f103为例

    异常类型 F103 在内核水平上搭载了一个异常响应系统, 支持为数众多的系统异常和外部中断.其中系统异常有8 个(如果把Reset 和HardFault 也算上的话就是10 个),外部中断有60个.除 ...

  5. springcloud3(六) 服务降级限流熔断组件Resilience4j

    代码地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-gateway/src/test/java/com/ ...

  6. Linux&C———进程间通信

    管道和有名管道 消息队列 共享内存 信号 套接字 由于进程之间的并不会像线程那样共享地址空间和数据空间,所以进程之间就必须有自己特有的通信方式,这篇博客主要介绍自己了解到的几种进程之间的通信方式,内容 ...

  7. 【Python+postman接口自动化测试】(6)Chrome开发者工具

    Chrome开发者工具 Elements: HTML元素面板,用于定位查看元素源代码 Console: js控制台面板,js命令行,查看前端日志 Sources: 资源面板,用于断点调试js Netw ...

  8. uni-app app端设置全屏背景色

    设置page:{样式},博主调试的时候在app端不起作用,设置配置文件的backgroundColor也没有用,所以博主就使用了一个稍微比较偏的办法解决了,没有用获取设备信息的api来实现 具体操作就 ...

  9. Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create()

    在Java中处理JSON格式的数据时,Google  Gson 是个不错的选择,用起来挺方便的,也有一定灵活性.我现在工作中在参与的两个项目里都有用它.不过它在处理Date格式时有个小陷阱,在不同环境 ...

  10. Qt概要

    Qt是面向对象的框架,使用特殊的代码生成扩展以及一些宏.是一个跨平台的C++图形用户界面.它是一款可以轻松的帮我们做界面的软件. Qt是1991年奇趣科技公司(2008 年 6 月被诺基亚收购)开发的 ...