http://www.elijahqi.win/2018/03/05/bzoj5194-usaco2018-febsnow-boots/
Description
到冬天了,这意味着下雪了!从农舍到牛棚的路上有N块地砖,方便起见编号为1…N,第i块地砖上积了fi英尺的雪
。在Farmer John的农舍的地窖中,总共有B双靴子,编号为1…B。其中某些比另一些结实,某些比另一些轻便。具
体地说,第i双靴子能够让FJ在至多si英尺深的积雪中行走,能够让FJ每步至多前进di。Farmer John从1号地砖出
发,他必须到达N号地砖才能叫醒奶牛们。1号地砖在农舍的屋檐下,N号地砖在牛棚的屋檐下,所以这两块地砖都
没有积雪。帮助Farmer John求出哪些靴子可以帮助他走完这段艰辛的路程。
Input
第一行包含两个空格分隔的整数N和B(1≤N,B≤10^5)。
第二行包含N个空格分隔的整数;第i个整数为fi,即i号地砖的积雪深度(0≤fi≤10^9)。输入保证f1=fN=0
下面B行,每行包含两个空格分隔的整数。第i+2行的第一个数为si,表示第i双靴子能够承受的最大积雪深度。
第i+2行的第二个数为di,表示第i双靴子的最大步长。输入保证0≤si≤10^9以及1≤di≤N-1
Output
输出包含N行
第i行包含一个整数:如果Farmer John能够穿着第i双靴子从1号地砖走到N号地砖,为1,否则为0
Sample Input
8 7
0 3 8 5 6 9 0 0
0 5
0 6
6 2
8 1
10 1
5 3
150 7
Sample Output
0
1
1
0
1
1
1
判断每双靴子能否完整的走完整段路
那么将靴子离线进来 然后每次把比靴子承受能力大的染黑 用并查集维护线段的连通性 针对每双靴子判断我最长不能走的有多大 看一看是否超过了我的跳跃能力 然后判断即可
#include<cstdio>
#include<algorithm>
#define N 110000
using namespace std;
inline char gc(){
static char now[1<<16],*S,*T;
if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
return *S++;
}
inline int read(){
int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=gc();}
while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=gc();
return x*f;
}
struct node{
int s,d,id;
}b[N],ti[N];
int fa[N],size[N],n,B;bool ans[N],black[N];
inline int find(int x){
while(x!=fa[x]) x=fa[x]=fa[fa[x]];return x;
}
inline bool cmp(const node &a,const node &b){return a.s>b.s;}
int main(){
//freopen("snowboots.in","r",stdin);
//freopen("snowboots.out","w",stdout);
n=read();B=read();int mx=0;
for (int i=1;i<=n;++i) ti[i].s=read(),ti[i].id=i;
for (int i=1;i<=B;++i) b[i].s=read(),b[i].d=read(),b[i].id=i;
sort(ti+1,ti+n+1,cmp);sort(b+1,b+B+1,cmp);
for (int i=1;i<=n;++i) fa[i]=i,size[i]=1;int now=1;
//for (int i=1;i<=B;++i) printf("%d %d %d\n",b[i].s,b[i].d,b[i].id);
//for (int i=1;i<=n;++i) printf("%d %d\n",ti[i].s,ti[i].id);
for (int i=1;i<=B;++i){
while(now<=n&&ti[now].s>b[i].s){
int id=ti[now].id;black[id]=1;mx=max(mx,1);
if (id>1)
if (black[id-1]){
int pre=find(id-1),f=find(id);
size[f]+=size[pre];fa[pre]=f;mx=max(mx,size[f]);
}
if (id<n&&black[id+1]){
int pos=find(id+1);fa[id]=pos;size[pos]+=size[id];mx=max(mx,size[pos]);
while(pos<=n&&black[pos+1]){
int f=find(pos+1);fa[pos]=f;size[f]+=size[pos];mx=max(mx,size[f]);pos=f;
}
}
// for (int i=1;i<=n;++i) printf("%d ",fa[i]);puts("");
// for (int i=1;i<=n;++i) printf("%d ",size[i]);puts("");
++now;
}if (mx<=b[i].d-1) ans[b[i].id]=1;
//if (b[i].id==667) printf("%d\n",mx);
//printf("%d\n",b[i].id);
}
for (int i=1;i<=B;++i) printf("%d\n",ans[i]);
return 0;
}