题:
题意:就是问1.你有没有一段长为m的连续区间,如果有的话就输出区间的最小的左端点,2把区间a~a+b的值制空。
思路:就是区间合并的裸题,我们需要存的是 区间左端点向右最多能延伸的区间长度,和区间右端点向左能够移动的区间长度,和区间最长连续的长度,之后我们每次查询,如果左子树长度比我们想要的长度长,那么久继续查询左子树,如果比他小,那我们就查询,左子树右端点可以延伸的长度和右子树左端点可以延伸的长度之和,如果还是不够那就查右子树。
上代码把:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mes(a) memset(a,0,sizeof(a));
const int maxn = 50000+10;
int lsum[maxn<<2] , rsum[maxn<<2] ,msum[maxn<<2],lazy[maxn<<2];
using namespace std;
void pushup(int rt,int m)
{
rsum[rt] = rsum[rt<<1|1];//
lsum[rt] = lsum[rt<<1];
if(lsum[rt] == m-(m>>1))//如果左子树左端点满了,就加上右子树上的值 。
{
lsum[rt] += lsum[rt<<1|1];
}
if(rsum[rt] == (m>>1))//同理 ,右子树右端点满了,就加上左子树上的值。
{
rsum[rt] += rsum[rt<<1];
}
msum[rt] = max(msum[rt<<1] , max(msum[rt<<1|1],rsum[rt<<1]+lsum[rt<<1|1]));//那么区间的最大值就是 左子树的最大值,和右子树的最大值和
//两个区间 相加。
}
void pushdown(int rt , int m)
{
if(lazy[rt] != -1)
{
//puts("-------------");
lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt];//把延迟标记下放
rsum[rt<<1] = lsum[rt<<1] = msum[rt<<1] = lazy[rt] ? 0 :m-(m>>1);//-1 表示没有延迟标记 ,0表示赋值,1表示制空
rsum[rt<<1|1] = lsum[rt<<1|1] = msum[rt<<1|1] = lazy[rt] ? 0:(m>>1);
lazy[rt] = -1;
}
}
void build(int l , int r ,int rt)
{
rsum[rt] = lsum[rt] = msum[rt] = r-l+1;
if(l == r)
{
return ;
}
int m = (l+r)>>1;
build(lson);
build(rson);
}
void update(int L,int R,int l,int r,int rt,int v)
{
// printf("L = %d R = %d\n",L,R);
if(l>=L&&R>=r)
{
lazy[rt] = v;
rsum[rt] = lsum[rt] = msum[rt] = v?0:(r-l+1);
return ;
}
pushdown(rt,r-l+1);
int m = (l+r)>>1;
if(m>=L)
update(L,R,lson,v);
if(R>m)
update(L,R,rson,v);
pushup(rt,r-l+1);
}
int query(int w,int l,int r,int rt)
{
if(l == r)
{
return l;
}
pushdown(rt , r-l+1);
int m = (r+l)>>1;
if(msum[rt<<1]>=w)
{
return query(w,lson);
}
else if(rsum[rt<<1]+lsum[rt<<1|1] >= w) return m-rsum[rt<<1]+1;
return query(w,rson);
}
int main()
{
int n ,m ;
while(scanf("%d%d",&n,&m) !=EOF)
{
int op,a,b;
memset(lazy , -1 , sizeof(lazy));
mes(msum);mes(rsum);mes(lsum);
build(1,n,1);
for(int i = 0 ; i < m ;i++)
{
scanf("%d",&op);
if(op == 1)
{
scanf("%d",&a);
if(msum[1]<a)
{
puts("0");
continue;
}
int q = query(a,1,n,1);
printf("%d\n",q);
update(q,q+a-1,1,n,1,1);
}
else
{
scanf("%d%d",&a,&b);
// printf(" MAX1 = %d\n",msum[1]);
update(a,a+b-1,1,n,1,0);
// printf(" MAX2 = %d\n",msum[1]);
}
}
}
return 0;
}