HDU2871 Memory Control

来源:互联网 发布:时时彩辅助软件 编辑:程序博客网 时间:2024/06/18 07:33
/*题意:对一段连续内存的重置,申请,释放,询问思路:New和Get是为区间合并,Free的查询时单点更新到底,Free的释放是成段更新特别注意Get的合并,这里卡了半天才发现。总结:其实就是三种线段树的综合,能定下心认真分析是不难的,多思考,戒急燥!AC!!!!也就是在家里没网没百度,硬生生自己想了两天终于搞出来了,还好2A不然不爱了。。一个心情大好,用手机热点写博客,算了不管了,流量伤就伤吧。。线段树就是越写越长,数据结构的通病么。。。*/
#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define ls (rt<<1)#define rs (rt<<1|1)const int MAXN = 50001;int lpa[MAXN<<2],rpa[MAXN<<2],mpa[MAXN<<2];int cover[MAXN<<2],begin[MAXN<<2],end[MAXN<<2];int tui[MAXN<<2];   // 左右端点的跟新标记,只下推不上传,单点询问更新到底int num[MAXN<<2];int n;struct Q{int f,e;};int max(int a, int b) { return a>b?a:b; }int min(int a, int b) { return a<b?a:b; }void build(int l, int r, int rt){lpa[rt] = rpa[rt] = mpa[rt] = r-l+1;cover[rt] = begin[rt] = end[rt] = num[rt] = 0;tui[rt] = 1;}void pushdown(int m, int len, int rt){if(cover[rt] != -1){cover[ls] = cover[rs] = cover[rt];lpa[ls] = rpa[ls] = mpa[ls] = cover[rt]? 0 : len-(len>>1);lpa[rs] = rpa[rs] = mpa[rs] = cover[rt]? 0 : (len>>1);if(tui[rt]){begin[ls] = begin[rs] = begin[rt];end[ls] = end[rs] = end[rt];num[ls] = num[rs] = cover[rt];tui[ls] = tui[rs] = tui[rt];tui[rt] = 0;}cover[rt] = -1;}}void pushup(int m, int len, int rt){lpa[rt] = lpa[ls];rpa[rt] = rpa[rs];if(lpa[rt] == len-(len>>1)) lpa[rt] += lpa[rs];if(rpa[rt] == (len>>1)) rpa[rt] += rpa[ls];mpa[rt] = rpa[ls] + lpa[rs];mpa[rt] = max(mpa[rt], max(lpa[rt], rpa[rt]));mpa[rt] = max(mpa[rt], max(mpa[ls], mpa[rs]));begin[rt] = begin[ls];end[rt] = end[rs];num[rt] = num[ls] + num[rs];if(end[ls] > m || begin[rs] && begin[rs] <= m) num[rt]--;if(cover[ls]!=-1 && cover[ls]==cover[rs]) cover[rt] = cover[ls];else cover[rt] = -1;/*if(num[ls]==1 && num[rs]==1 && num[rt]==1) cover[rt] = 1;else if(num[ls]==0 && num[rs]==0) cover[rt] = 0;else cover[rt] = -1;*/}int query(int len, int l, int r, int rt){if(l == r){return l;}else{int m = (l+r)>>1;pushdown(m,r-l+1,rt);if(mpa[ls] >= len) return query(len,lson);else if(rpa[ls]+lpa[rs] >= len) return m-rpa[ls]+1;else return query(len, rson);}}void update(int L, int R, int col, int l, int r, int rt){if(L<=l && r<=R){cover[rt] = col;num[rt] = col;lpa[rt] = rpa[rt] = mpa[rt] = col? 0 : r-l+1;tui[rt] = 1;if(col){begin[rt] = L;end[rt] = R;}else begin[rt] = end[rt] = 0;}else{int m = (l+r)>>1;pushdown(m,r-l+1,rt);if(L <= m) update(L,R,col,lson);if(R >  m) update(L,R,col,rson);pushup(m,r-l+1,rt);}}Q Pquery(int x, int l, int r, int rt){if(l == r){Q tt = {begin[rt],end[rt]};return tt;}else{int m = (l+r)>>1;pushdown(m,r-l+1,rt);if(x <= m) return Pquery(x,lson);else return Pquery(x,rson);}}int Gquery(int x, int l, int r, int rt){if(l == r){return begin[rt];}else{int m = (l+r)>>1;pushdown(m,r-l+1,rt);if(num[ls] >= x) return Gquery(x,lson);else{int tx = x - num[ls];if(end[ls] > m || begin[rs] && begin[rs] <= m) tx++;return Gquery(tx,rson);}}}int main(){int q;int x;char s[20];while(~scanf("%d%d", &n, &q)){build(1,n,1);while(q--){scanf("%s", s);if(s[0] == 'R'){build(1,n,1);printf("Reset Now\n");}else{scanf("%d", &x);if(s[0] == 'N'){if(mpa[1] < x) printf("Reject New\n");else{int p = query(x,1,n,1);printf("New at %d\n", p);update(p,p+x-1,1,1,n,1);}}else if(s[0] == 'F'){Q tt = Pquery(x,1,n,1);if(!tt.f && !tt.e) printf("Reject Free\n");else{printf("Free from %d to %d\n", tt.f, tt.e);update(tt.f,tt.e,0,1,n,1);}}else{if(num[1] < x) printf("Reject Get\n");else{printf("Get at %d\n", Gquery(x,1,n,1));}}}}printf("\n");}return 0;}