您的位置:首页 > 其它

BZOJ3958: [WF2011]Mummy Madness

2017-04-26 19:38 351 查看
可以发现,你被抓住的时间满足二分性,因为若在时间x你被抓住了,那么对于任意时间y>x,木乃伊都一定能抓住你

那么二分这个时间,你能走到的地方是一个矩形,同时每个木乃伊能走到的地方也是一个矩形,扫描线扫一下,若整个矩形都被覆盖了就会被抓住

(只处理每个木乃伊的矩形和你走到的矩形的交的部分,不然可能会T)

code:

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

inline void read(int &x)
{
char c; int f=1;
while(!((c=getchar())>='0'&&c<='9')) if(c=='-') f=-f;
x=c-'0';
while((c=getchar())>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0';
x*=f;
}
inline void up(int &x,const int y){if(x<y)x=y;}
inline int _max(const int &x,const int &y){return x>y?x:y;}
inline int _min(const int &x,const int &y){return x<y?x:y;}
const int maxn = 210000;
const int maxc = 1010000;

int n,C;
struct P{int x,y;}p[maxn];

struct edge
{
int l,r,c,nex;
edge(){}
edge(const int _l,const int _r,const int _c,const int _nex){l=_l;r=_r;c=_c;nex=_nex;}
}a[maxn<<1]; int len,fir[maxc<<1];
inline void ins(const int x,const int l,const int r,const int c)
{
a[++len]=edge(l,r,c,fir[x]);fir[x]=len;
}

struct segment
{
int flag,c;
}seg[maxc<<4];
int lx,rx,c;
void upd(const int x,const int l,const int r)
{
if(lx<=l&&r<=rx) { seg[x].flag+=c; seg[x].c+=c; return; }
if(rx<l||r<lx) return;
upd(x<<1,l,l+r>>1),upd((x<<1)|1,(l+r>>1)+1,r);
seg[x].c=seg[x].flag+_min(seg[x<<1].c,seg[(x<<1)|1].c);
}

bool Judge(const int m)
{
len=0; for(int i=0;i<=2*C+1;i++) fir[i]=0;

for(int i=1;i<=n;i++)
{
int d=m+max(p[i].y-m,-m),u=m+min(p[i].y+m,m);
int l=m+max(p[i].x-m,-m),r=m+min(p[i].x+m,m);
if(u>=0&&d<=u) ins(d,l,r,1),ins(u+1,l,r,-1);
}

bool flag=false;
for(int i=0;i<=2*m;i++)
{
for(int k=fir[i];k;k=a[k].nex)
{
lx=a[k].l,rx=a[k].r,c=a[k].c;
if(lx<=rx) upd(1,0,m<<1);
}
if(!seg[1].c) flag=true;
}
for(int k=fir[2*m+1];k;k=a[k].nex)
{
lx=a[k].l,rx=a[k].r,c=a[k].c;
if(lx<=rx) upd(1,0,m<<1);
}
return flag;
}
int solve()
{
int l=1,r=C;
while(l<=r)
{
int mid=l+r>>1;
if(Judge(mid)) l=mid+1;
else r=mid-1;
}
return l-1;
}

int main()
{
for(int t=1;scanf("%d",&n)&&n!=-1;t++)
{
C=0;
for(int i=1;i<=n;i++)
{
int x,y; read(x); read(y);
p[i].x=x; p[i].y=y;
up(C,abs(x)); up(C,abs(y));
}
int re=solve()+1;
printf("Case %d: ",t);
if(re==C+1) printf("never\n");
else printf("%d\n",re);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: