线段树之区间合并+二分查找,和hotel哪一题类似,,
AC代码:
#include <iostream> #include<string.h> #include<algorithm> #include<vector> #include<cstdio> #define CLR(arr,val) memset(arr,val,sizeof(arr)) #define N 50005 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define M(a,b) (a+b)>>1 using namespace std; typedef struct{ int r; int l; int lsum; int rsum; int msum; int col; }Tree; Tree Node[N<<2]; typedef struct { int x; int y; }Block; bool cmp(const Block& a,const Block& b) { return a.x<b.x; } int Max(int a,int b,int c){ a=a>b?a:b; a=a>c?a:c; return a; } vector<Block>v; void push_down(int rt,int s){ if(Node[rt].col!=-1){ Node[rt<<1].col=Node[rt<<1|1].col=Node[rt].col; Node[rt<<1].lsum=Node[rt<<1].rsum=Node[rt<<1].msum= Node[rt].col?s-(s>>1):0; Node[rt<<1|1].lsum=Node[rt<<1|1].rsum=Node[rt<<1|1].msum=Node[rt].col?(s>>1):0; Node[rt].col=-1; } } void push_up(int rt,int s){ Node[rt].lsum=Node[rt<<1].lsum; Node[rt].rsum=Node[rt<<1|1].rsum; if(Node[rt<<1].lsum==(s-(s>>1))) Node[rt].lsum+=Node[rt<<1|1].lsum; if(Node[rt<<1|1].rsum==(s>>1)) Node[rt].rsum+=Node[rt<<1].rsum; Node[rt].msum=Max(Node[rt<<1].msum,Node[rt<<1|1].msum,Node[rt<<1].rsum+Node[rt<<1|1].lsum); } void build(int l,int r,int rt){ if(l==r){ Node[rt].l=Node[rt].r=l; Node[rt].lsum=Node[rt].rsum=Node[rt].msum=1; Node[rt].col=-1; return; } int m=M(l,r); build(lson); build(rson); Node[rt].l=l; Node[rt].r=r; Node[rt].lsum=Node[rt].rsum=Node[rt].msum=r-l+1; Node[rt].col=-1; } void updata(int L,int R,int cnt,int l,int r,int rt) { if(L<=l&&R>=r){ Node[rt].col=cnt; Node[rt].lsum=Node[rt].rsum=Node[rt].msum=cnt?r-l+1:0; return; } push_down(rt,r-l+1); int m=M(l,r); if(L<=m) updata(L,R,cnt,lson); if(R>m) updata(L,R,cnt,rson); push_up(rt,r-l+1); } int Quary(int p,int l,int r,int rt){ if(l==r) return l; push_down(rt,r-l+1); int m=M(l,r); if(Node[rt<<1].msum>=p) return Quary(p,lson); else if((Node[rt<<1].rsum+Node[rt<<1|1].lsum)>=p) return (m-Node[rt<<1].rsum+1); return Quary(p,rson); } void in(int &a) { char ch; while((ch=getchar())<'0'||ch>'9'); for( a=0;ch>='0'&&ch<='9';ch=getchar()) a=a*10+ch-'0'; } int n,m; int main() { while(~scanf("%d%d",&n,&m)) { char ch[10]; build(1,n,1); v.clear(); while(m--){ scanf("%s",ch); if(ch[0]=='N'){ int a;in(a); if(Node[1].msum<a) printf("Reject New\n"); else{ int ans=Quary(a,1,n,1); printf("New at %d\n",ans); updata(ans,ans+a-1,0,1,n,1); Block pos; pos.x=ans,pos.y=ans+a-1; vector<Block>::iterator it=upper_bound(v.begin(),v.end(),pos,cmp); v.insert(it,pos); } } else if(ch[0]=='F'){ int a;in(a); Block pos; pos.x=a,pos.y=a; vector<Block>::iterator it=upper_bound(v.begin(),v.end(),pos,cmp); int ans=it-v.begin()-1; if(ans==-1||v[ans].y<a) printf("Reject Free\n"); else { printf("Free from %d to %d\n",v[ans].x,v[ans].y); updata(v[ans].x,v[ans].y,1,1,n,1); v.erase(v.begin()+ans); } } else if(ch[0]=='R'){ printf("Reset Now\n"); v.clear(); updata(1,n,1,1,n,1); } else { int a;in(a); if(v.size()>=a) printf("Get at %d\n",v[a-1].x); else printf("Reject Get\n"); } } printf("\n"); }return 0; }