[BZOJ3958][WF2011]Mummy Madness(二分+扫描线+线段树)

题目描述

传送门

题目大意:一个正方形的网格,你与木乃伊轮流移动(你走出第一步)。轮到你时,你可以移动到相邻的8个格子之一,或者站着不动。轮到木乃伊时,每个木乃伊会移动到其相邻的格子之一,使得他与你的欧几里得距离尽量小(假设你与木乃伊都站在格子的中心位置)。允许多个木乃伊同时占据同一个格子。
在每个单位时间内,你先做出移动,然后木乃伊做出移动。如果你与任何一个木乃伊站在同一位置,你会被抓住。当然,你试图尽量长时间避免被抓住。经过多少单位时间你会被抓住呢?

题解

首先二分答案,然后将H和每一个木乃伊能在这个时间内能到达的点标记出来,可以发现是n+1个正方形。没有被抓住的条件是H所确定的正方形不是所有木乃伊所确定的正方形的并的子集。
用扫描线求解。首先将纵坐标离散,然后将木乃伊的正方形分解成左右两个线段,然后按照横坐标排序。每一次遇到一条线段在范围内加减,然后每一次判断是否被完全覆盖了即可,注意顺序应该为加、统计答案、减。
但是有一些特殊的边界条件需要判断:如果存在某一列根本就没有操作不能跳过去,也应该判断;H的左边界和右边界要判断;如果有某一行为空的话在离散化的时候应该往里加进去一行(试了很久不加点的方法都不科学qwq

代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define N 100005

int T,n,Max,Min,LSH,cnt,ans;
struct P{
  int x,y;}p[N];
struct LINE{
  int x,l,r,val;}line[N<<1];
int lsh[400004],cover[1000005],sum[1000005];

void clear()
{
    Max=Min=LSH=cnt=ans=0;
    memset(lsh,0,sizeof(lsh));
}
int cmp(LINE a,LINE b)
{
    return a.x<b.x||(a.x==b.x&&a.val>b.val);
}
void update(int now,int l,int r)
{
    if (cover[now]) sum[now]=r-l+1;
    else if (l==r) sum[now]=
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值