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的更多相关文章
- 洛谷 P3438 - [POI2006]ZAB-Frogs(乱搞/李超线段树)
题面传送门 首先一眼二分答案,我们假设距离 \((i,j)\) 最近的 scarefrog 离它的距离为 \(mn_{i,j}\),那么当我们二分到 \(mid\) 时我们显然只能经过 \(mn_{i ...
- 分布式系统理论进阶 - Raft、Zab
引言 <分布式系统理论进阶 - Paxos>介绍了一致性协议Paxos,今天我们来学习另外两个常见的一致性协议——Raft和Zab.通过与Paxos对比,了解Raft和Zab的核心思想.加 ...
- paxos(chubby) vs zab(Zookeeper)
参考: Zookeeper的一致性协议:Zab Chubby&Zookeeper原理及在分布式环境中的应用 Paxos vs. Viewstamped Replication vs. Zab ...
- ZooKeeper之ZAB协议
ZooKeeper为高可用的一致性协调框架,自然的ZooKeeper也有着一致性算法的实现,ZooKeeper使用的是ZAB协议作为数据一致性的算法,ZAB(ZooKeeper Atomic Broa ...
- POJ 1659 Frogs' Neighborhood(Havel-Hakimi定理)
题目链接: 传送门 Frogs' Neighborhood Time Limit: 5000MS Memory Limit: 10000K Description 未名湖附近共有N个大小湖泊L ...
- 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 ...
- 第三章 深入 ZAB 协议
上一节介绍了ZAB协议的内容,本节将从系统模型.问题描述.算法描述和运行分析四方面来深入了解 ZAB 协议. 系统模型 在一个由一组进程 n ={P1,P2,...Pn}组成的分布式系统中,每一个进程 ...
- 第二章 ZAB协议介绍
ZAB ( ZooKeeper Atomic Broadcast , ZooKeeper 原子消息广播协议)是zookeeper数据一致性的核心算法. ZAB 协议并不像 Paxos 算法那样,是一种 ...
- 【BZOJ】【1520】【POI2006】Szk-Schools
网络流/费用流 比较裸的一道题 依旧是二分图模型,由源点S连向每个学校 i (1,0),「注意是连向第 i 所学校,不是连向学校的标号m[i]……唉这里WA了一次」 然后对于每所学校 i 连接 j+n ...
随机推荐
- 【UE4 C++】播放声音、特效
播放声音 PlaySoundAtLocation() USoundCue* HitSound = LoadObject<USoundCue>(this, TEXT("SoundC ...
- 【UE4 设计模式】组件模式 Components Pattern
概述 描述 在单一实体跨越了多个领域时,为了保持领域之间相互解耦,可以将每部分代码放入各自的组件类中,将实体简化为组件的容器. 套路 参考 UE4中的 Componet 组件使用方式 使用场景 有一个 ...
- Codeforces1573B
### 问题描述 - 给你两个数组,a数组里面是1 - 2n中的奇数任意顺序排列组成,b数组里面是1 - 2n中的奇数任意顺序排列组成. - 问你最少需要多少次操作能让a的字典序小于b. ### 思路 ...
- 新產品SWOT分析實例
推出新产品需要解决四个行销支柱: 价格 产品 促销 销售地点 要分析这些方面,请检查您的优势.劣势.机会和威胁,以帮助您在运行第一个广告或举行第一次促销之前将风险降至最低,并最大限度地利用资源.SWO ...
- eureka服务端和客户端的简单搭建
本篇博客简单记录一下,eureka 服务端和 客户端的简单搭建. 目标: 1.完成单机 eureka server 和 eureka client 的搭建. 2.完成eureka server 的添加 ...
- Noip模拟13 2021.7.13:再刚题,就剁手&&生日祭
T1 工业题 这波行列看反就非常尴尬.....口糊出所有正解想到的唯独行列看反全盘炸列(因为和T1斗智斗勇两个半小时...) 这题就是肯定是个O(n+m)的,那就往哪里想,a,b和前面的系数分开求,前 ...
- Azure File Storage(一)为本地机器配置网络磁盘
一,引言 本地机器硬盘空间不够了怎么办?重要文件不想存储在本地硬盘怎么办?加外接移动硬盘:或者换大容量存储设备,都是解决方案.但是每次都得携带,还得考虑当前设备是否支持外接硬盘. 1,这个时候 Win ...
- 如何系统学习C 语言(中)之 指针篇
谈到指针,我们可能会想到钟表上的指针,但这里的指针不是现实生活中看得见摸得着的钟表上的指针,c 语言中的指针只存在于逻辑思维中,物理上并不存在. 同时,指针也是C 语言中最精华的部分,通过灵活地运用指 ...
- 【编译原理】LL1文法语法分析器
上篇文章[编译原理]语法分析--自上向下分析 分析了LL1语法,文章最后说给出栗子,现在补上去. 说明: 这个语法分析器是利用LL1分析方法实现的. 预测分析表和终结符以及非终结符都是针对一个特定文法 ...
- Vue首屏性能优化组件
Vue首屏性能优化组件 简单实现一个Vue首屏性能优化组件,现代化浏览器提供了很多新接口,在不考虑IE兼容性的情况下,这些接口可以很大程度上减少编写代码的工作量以及做一些性能优化方面的事情,当然为了考 ...