线段树区间合并果题。
传送门:http://poj.org/problem?id=3667
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <algorithm>
const int MAXN = 50005;
struct Node {
int x,y;
int maxlen;
int llen,rlen;
int lazy;
}t[MAXN << 2];
void Push_Up(int rt) {
//Update llen and rlen;
t[rt].llen = t[rt<<1].llen;
t[rt].rlen = t[rt<<1|1].rlen;
if(t[rt<<1].llen == t[rt<<1].y - t[rt<<1].x + 1) t[rt].llen += t[rt<<1|1].llen;
if(t[rt<<1|1].rlen == t[rt<<1|1].y - t[rt<<1|1].x + 1) t[rt].rlen += t[rt<<1].rlen;
//Update maxlen;
t[rt].maxlen = t[rt<<1].maxlen;
if(t[rt<<1|1].maxlen > t[rt].maxlen) t[rt].maxlen = t[rt<<1|1].maxlen;
if(t[rt<<1].rlen + t[rt<<1|1].llen > t[rt].maxlen) t[rt].maxlen = t[rt<<1].rlen + t[rt<<1|1].llen;
}
void Push_Down(int rt) {
if(t[rt].lazy != -1) {
t[rt<<1].lazy = t[rt].lazy;
t[rt<<1|1].lazy = t[rt].lazy;
if(t[rt].lazy == 0) {
t[rt<<1].llen = t[rt<<1].rlen = t[rt<<1].maxlen = (t[rt<<1].y - t[rt<<1].x + 1);
t[rt<<1|1].llen = t[rt<<1|1].rlen = t[rt<<1|1].maxlen = (t[rt<<1|1].y - t[rt<<1|1].x + 1);
}
else {
t[rt<<1].llen = t[rt<<1].rlen = t[rt<<1].maxlen = 0;
t[rt<<1|1].llen = t[rt<<1|1].rlen = t[rt<<1|1].maxlen = 0;
}
t[rt].lazy = -1;
}
}
void Build(int x,int y,int rt) {
t[rt].x = x; t[rt].y = y; t[rt].lazy = -1;
if(x == y) {
t[rt].maxlen = 1; t[rt].llen = 1; t[rt].rlen = 1;
return ;
}
int mid = (x + y) >> 1;
Build(x,mid,rt<<1);
Build(mid+1,y,rt<<1|1);
Push_Up(rt);
}
void Update(int x,int y,int rt,int l,int r,int v) {
if(x >= l && y <= r) {
t[rt].lazy = v;
if(v == 0) {
t[rt].maxlen = t[rt].llen = t[rt].rlen = (y - x + 1);
}
else {
t[rt].maxlen = t[rt].llen = t[rt].rlen = 0;
}
return ;
}
Push_Down(rt);
int mid = (x + y) >> 1;
if(mid >= l) {
Update(x,mid,rt<<1,l,r,v);
}
if(mid < r) {
Update(mid+1,y,rt<<1|1,l,r,v);
}
Push_Up(rt);
}
int Query(int x,int y,int rt,int w) {
if(x == y) {
return x;
}
//printf("x : %d y : %d rt : %d maxlen : %d w : %d\n",x,y,rt,t[rt].maxlen,w);
Push_Down(rt);
int mid = (x + y) >> 1;
if(t[rt<<1].maxlen >= w) return Query(x,mid,rt<<1,w);
if(t[rt<<1].rlen + t[rt<<1|1].llen >= w) return (t[rt<<1].y - t[rt<<1].rlen + 1);
if(t[rt<<1|1].maxlen >= w) return Query(mid+1,y,rt<<1|1,w);
return 0;
}
void print(int x,int y,int rt) {
printf("x : %d y : %d maxlen : %d lazy : %d\n",x,y,t[rt].maxlen,t[rt].lazy);
if(x == y) return ;
int mid = (x + y) >> 1;
print(x,mid,rt<<1);
print(mid+1,y,rt<<1|1);
}
void Deal_with() {
int n,m;
while(~scanf("%d %d",&n,&m)) {
int tempa,w,pos,len;
Build(1,n,1);
//print(1,n,1);
for(int i = 1 ; i <= m ; i++) {
scanf("%d",&tempa);
if(tempa == 1) {
scanf("%d",&w);
pos = Query(1,n,1,w);
printf("%d\n",pos);
if(pos)
Update(1,n,1,pos,pos+w-1,1);
//print(1,n,1);
}
else{
scanf("%d %d",&pos,&len);
Update(1,n,1,pos,pos+len-1,0);
}
}
}
}
int main(void) {
//freopen("a.in","r",stdin);
Deal_with();
return 0;
}