线段树的题, 其中NODE节点中额外保存三个信息: lval保存的是本节点中, 以l为起点往右的最长连续空位; rval保存的是以r-1为起点往左的最长连续空位; sum保存的是本节点区间[l,r)中最长的连续空位.
/******************************************************************************* # Author : Neo Fung # Email : [email protected] # Last modified: 2012-01-18 20:11 # Filename: HDU1689 Just a Hook.cpp # Description : ******************************************************************************/ #ifdef _MSC_VER #define DEBUG #endif #include <fstream> #include <stdio.h> #include <iostream> #include <string.h> #include <string> #include <limits.h> #include <algorithm> #include <math.h> #include <numeric> #include <functional> #include <ctype.h> #define L(x) (x<<1) #define R(x) (x<<1|1) #define MAX 50010 using namespace std; struct NODE { int l,r,lval,rval,sum; }node[MAX*4]; void init() { memset(node,'\0',sizeof(node)); } void build(const int &t , const int &l,const int &r) { node[t].l=l; node[t].r=r; node[t].lval=node[t].rval=node[t].sum=r-l; if(l==r-1) return; int mid=(l+r)>>1; build(L(t),l,mid); build(R(t),mid,r); } void inline setNode(const int &t,const int &state) { int len=node[t].r-node[t].l; node[t].lval=node[t].rval=node[t].sum=len*state; } int inline getLen(const int &t) { return node[t].r-node[t].l; } void update(const int &t,const int &l,const int &r,const int &state) { const int len=getLen(t); if(node[t].l>=l && node[t].r<=r) //整段设置 { setNode(t,state); return; } if(node[t].sum==len || node[t].sum==0) //Lazy更新 { int st=0; if(node[t].sum) st=1; setNode(L(t),st); setNode(R(t),st); } int mid=(node[t].l+node[t].r)>>1; if(l>=mid) update(R(t),l,r,state); else if(r<=mid) update(L(t),l,r,state); else { update(L(t),l,mid,state); update(R(t),mid,r,state); } node[t].lval=node[L(t)].lval; if(node[L(t)].lval==getLen(L(t))) node[t].lval+=node[R(t)].lval; node[t].rval=node[R(t)].rval; if(node[R(t)].rval==getLen(R(t))) node[t].rval+=node[L(t)].rval; node[t].sum=node[L(t)].rval+node[R(t)].lval; node[t].sum=max(node[t].sum,node[L(t)].sum); node[t].sum=max(node[t].sum,node[R(t)].sum); } int query(const int &t,const int &need) { if(node[t].sum<need) return -1; if(node[t].l==node[t].r-1) return node[t].l; if(node[t].lval>=need) return node[t].l; if(node[L(t)].sum>=need) return query(L(t),need); else if(node[L(t)].rval+node[R(t)].lval>=need) return node[L(t)].r-node[L(t)].rval; else return query(R(t),need); } int main(void) { #ifdef DEBUG freopen("../stdin.txt","r",stdin); freopen("../stdout.txt","w",stdout); #endif int n,m; int s,x,d; while(~scanf("%d%d",&n,&m)) { init(); build(1,0,n); while(m--) { scanf("%d",&s); if(s==1) { scanf("%d",&d); int ans=query(1,d); printf("%d\n",ans+1); if(ans>=0) update(1,ans,ans+d,0); } else { scanf("%d%d",&x,&d); update(1,x-1,x+d-1,1); } } } return 0; }