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. 【UE4 设计模式】工厂方法模式 Factory Method Pattern 及自定义创建资源

    概述 描述 又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式,或者多态工厂(Polymorphic Factory)模式 工厂父类负责定义创建产品对象的公共接口,而工厂子类 ...

  2. Vue CLI 5 和 vite 创建 vue3.x 项目以及 Vue CLI 和 vite 的区别

    这几天进入 Vue CLI 官网,发现不能选择 Vue CLI 的版本,也就是说查不到 vue-cli 4 以下版本的文档. 如果此时电脑上安装了 Vue CLI,那么旧版安装的 vue 项目很可能会 ...

  3. OO第四单元作业总结及课程总结

    一.本单元作业架构设计 1.第一次作业 本单元首次接触到UML以及相关概念,在面对第一次作业时首先花了很大功夫去阅读官方接口中各种UmlElement的代码,才理解了输入的模型元素中各属性的含义.总的 ...

  4. Des加密解密(公共方法)

    1 public class Des 2 { 3 public static string Encrypt(string message, string key) 4 { 5 DES des = ne ...

  5. P2598 [ZJOI2009]狼和羊的故事(最小割)

    P2598 [ZJOI2009]狼和羊的故事 说真的,要多练练网络流的题了,这么简单的网络流就看不出来... 题目要求我们要求将狼和羊分开,也就是最小割,(等等什么逻辑...头大....) 我们这样想 ...

  6. popStar手机游戏机机对战程序

    DFS算,五分钟如果答案没有更新,那个解一般来说就很优了. #include <cstdio> #include <iostream> #include <string. ...

  7. DeWeb和WebXone的区别

    DeWeb和WebXone的区别 相同点: 1 两者为同一开发者研发.QQ:45300355,碧树西风 2 都是为了解决Delphi开发Web的问题 区别: 1 WebXone采用的ActiveX/N ...

  8. QuantumTunnel:协议路由 vs 端口路由

    本篇来聊一下内网穿透中流量转发的问题 内网穿透和核心逻辑是根据流量的路由信息准确地将公网流量路由到指定的机器端口上,从而完成一次流量的内网穿透. 这里有一个核心问题,路由信息从哪里获取? 常见的有将路 ...

  9. prometheus(3)之grafan可视化展现

    可视化UI界面Grafana的安装和配置 Grafana介绍 Grafana是一个跨平台的开源的度量分析和可视化工具,可以将采集的数据可视化的展示,并及时通知给告警接收方.它主要有以下六大特点: 1. ...

  10. Cain工具的使用

    这次是用windows xp当肉鸡,用Windows2003进行监听 这是一个基于ARP协议的漏洞的攻击 先要确认两个虚拟机之间能够互相ping通和都能正常访问网页 首先安装好Cain后,张这个样子: ...