本题目重做感受颇多,
思考的深度决定了对线段树的掌握程度,只有自己创生的才是自己的啊。
本题用到了三个维护值,sum表示区间最长连续区间,lsum为区间左面最长连续区间长。rsum同理。
现在来说明sum为什么具有 可维护性,
线段树的可维护性是相对于更新区间而言的,因为更新的logn个区间总是被刷成全空房间,或全满房间,所以这几个区间的三个属性都可以得到维护,并且具有向上的合并性质
所以可以维护,一旦可以维护,那就啥也不说了。
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define rep(i,n) for(int (i)=0;(i)<(n);i++)
#define Rep(i,n) for(int (i)=1;(i)<=(n);i++)
const int N = 51111;
int sum[N<<2],col[N<<2],lsum[N<<2],rsum[N<<2];
void push_up(int l,int r,int rt){
sum[rt] = max(sum[rt<<1],sum[rt<<1|1]);
sum[rt] = max(sum[rt],rsum[rt<<1]+lsum[rt<<1|1]);
int v = lsum[rt<<1];
int m = (l+r)>>1;
lsum[rt] = (v==m-l+1 ? v+lsum[rt<<1|1]:v);
v = rsum[rt<<1|1];
rsum[rt] = (v==r-m ? v+rsum[rt<<1]:v);
}
void upd_one_seg(int l,int r,int rt,int f){
if(!f){
sum[rt] = lsum[rt] = rsum[rt] = r-l+1;
}
else {
sum[rt] = lsum[rt] = rsum[rt] = 0;
}
}
void push_down(int l,int r,int rt){
if(col[rt]!=-1){
int m = (l+r)>>1;
upd_one_seg(lson,col[rt]);
upd_one_seg(rson,col[rt]);
col[rt<<1] = col[rt<<1|1] = col[rt];
col[rt] = -1;
}
}
void build(int l,int r,int rt){
col[rt] = -1;
if(l==r){
sum[rt] = lsum[rt] = rsum[rt] = 1;
return ;
}
int m = (l+r)>>1;
build(lson);
build(rson);
push_up(l,r,rt);
}
void update(int l,int r,int rt,int L,int R,int f){
if(L<=l&&r<=R){
col[rt] = f;
upd_one_seg(l,r,rt,f);
return ;
}
push_down(l,r,rt);
int m = (l+r)>>1;
if(L<=m) update(lson,L,R,f);
if(R>m) update(rson,L,R,f);
push_up(l,r,rt);
}
int query(int l,int r,int rt,int len){
if(l==r){
if(sum[rt] == len) return l;
return 0;
}
push_down(l,r,rt);
int m = (l+r)>>1;
if(sum[rt<<1]>=len) return query(lson,len);
int mid = rsum[rt<<1]+lsum[rt<<1|1];
if(mid >= len){return m-rsum[rt<<1]+1;}
else if(sum[rt<<1|1]>=len) return query(rson,len);
return 0;
}
int n,m;
int main()
{
while(scanf("%d %d",&n,&m)==2){
build(1,n,1);
while(m--){
int cmd,x,y;
scanf("%d",&cmd);
if(cmd == 1){
scanf("%d",&x);
int p = query(1,n,1,x);
printf("%d\n",p);
if(p){
update(1,n,1,p,p+x-1,1);
}
}
else {
scanf("%d %d",&x,&y);
update(1,n,1,x,x+y-1,0);
}
}
}
return 0;
}