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
题解
考试模拟题。。
把靴子按深度排序,格子也按深度排
然后离线把格子一个一个加进去
如果当前的靴子的深度为5,那么格子深度<5的全部加入线段中
问题转化为维护最长一段没有加入的格子
然后直接线段树。。
#include
#include
#include
#include
#include
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline void write(int x)
{
if(!x) return (void)puts("0");
if(x<0) putchar('-'),x=-x;
static short s[25],t;
while(x) s[++t]=x%10,x/=10;
while(t) putchar('0'+s[t--]);
putchar('\n');
}
struct ozy666
{
int y,up,op;
}a[110000],b[110000];int n,m;
bool cmp(ozy666 n1,ozy666 n2){return n1.yy;}
struct node
{
int lc,rc,l,r,mx;
int lb,rb;//左边开始最长一段 右边开始最长一段
}tr[210000];int trlen;
void bt(int l,int r)
{
int now=++trlen;
tr[now].l=l;tr[now].r=r;
tr[now].mx=tr[now].lb=tr[now].rb=r-l+1;
tr[now].lc=tr[now].rc=-1;
if(lint mid=(l+r)/2;
tr[now].lc=trlen+1;bt(l,mid);
tr[now].rc=trlen+1;bt(mid+1,r);
}
}
void upd(int now)
{
int lc=tr[now].lc,rc=tr[now].rc;
tr[now].mx=max(tr[lc].mx,tr[rc].mx);
tr[now].mx=max(tr[now].mx,tr[lc].rb+tr[rc].lb);
tr[now].lb=tr[lc].lb;
if(tr[lc].lb==tr[lc].r-tr[lc].l+1)tr[now].lb=tr[lc].lb+tr[rc].lb;
tr[now].rb=tr[rc].rb;
if(tr[rc].rb==tr[rc].r-tr[rc].l+1)tr[now].rb=tr[rc].rb+tr[lc].rb;
}
void change(int now,int p)
{
if(tr[now].l==tr[now].r)
{
tr[now].mx=tr[now].lb=tr[now].rb=0;
return ;
}
int lc=tr[now].lc,rc=tr[now].rc;
int mid=(tr[now].l+tr[now].r)/2;
if(p<=mid)change(lc,p);
else change(rc,p);
upd(now);
}
int answer[110000];
int main()
{
n=read();m=read();
for(int i=1;i<=n;i++)a[i].y=read(),a[i].op=i;
for(int i=1;i<=m;i++)b[i].y=read(),b[i].up=read(),b[i].op=i;//保护 跳跃
sort(a+1,a+1+n,cmp);
sort(b+1,b+1+m,cmp);
bt(1,n);
int LA;
for(int i=1;i<=n;i++)
{
if(a[i].y>b[1].y){LA=i;break;}
change(1,a[i].op);
}
if(tr[1].mx1].up)answer[b[1].op]=1;
else answer[b[1].op]=0;
for(int i=2;i<=m;i++)
{
if(b[i].y==b[i-1].y)
{
if(tr[1].mx1;
else answer[b[i].op]=0;
}
else
{
for(int j=LA;j<=n;j++)
{
if(a[j].y>b[i].y){LA=j;break;}
change(1,a[j].op);
}
if(tr[1].mx1;
else answer[b[i].op]=0;
}
}
for(int i=1;i<=m;i++)write(answer[i]);
return 0;
}