设为首页 加入收藏

TOP

hdu 2871 Memory Control 伸展树区间合并(一)
2014-11-23 21:34:22 来源: 作者: 【 】 浏览:8
Tags:hdu 2871 Memory Control 伸展 区间 合并
题意:就是对一个区间的四种操作,NEW x,占据最左边的连续的x个单元,Free x 把x单元所占的连续区间清空 , Get x 把第x次占据的区间输出来, R 清空整个区间。
解法:很明显的区间合并,跟hotel那题差不多,貌似多了Free,Get操作,
我们可以用一个vector保存已经申请的区间,然后要Free x就在vector里面二分找到x所在的区间即可, Get也是二分一下即可, 其它操作可以用线段树或者伸展树操作。
这题主要是练了一下伸展树,这题也算基础, 但还是调了好久,真心难调,锻炼调试能力。
伸展树:
#include 
#include 
#include 
#include 
using namespace std;
const int maxn = 50006;
#define L ch[x][0]
#define R ch[x][1]
#define KT ch[ ch[root][1]][0]
#define mp make_pair
typedef pair pii;
int n;
struct splayTree {
    int sz[maxn], pre[maxn], ch[maxn][2];
    int top, root;
    int ls[maxn], rs[maxn], ms[maxn], col[maxn], val[maxn];
    void rotate(int &x, int f) {
        int y = pre[x], z = pre[y];
        down(y); down(x);
        ch[y][!f] = ch[x][f];
        pre[ch[x][f]] = y;
        pre[x] = pre[y];
        if(z) ch[z][ch[z][1] == y] = x;
        ch[x][f] = y;
        pre[y] = x;
        up(y);
    }
    void splay(int &x, int g) {
    	down(x);
          while(pre[x] != g) {
              int y = pre[x], z = pre[y];
              if(z == g) rotate(x, ch[y][0] == x);
              else {
                  int f = (ch[z][0] == y);
                  ch[y][!f] == x   rotate(y, f) : rotate(x, !f);
                  rotate(x, f);
              }
          }
          up(x);
          if(!g) root = x;
      }
    void rto(int k, int g) {
        int x = root;
        while(sz[L] != k) {
        	down(x);
            if(sz[L] > k) x = L;
            else {
                k -= sz[L]+1;
                x = R;
            }
        }
        splay(x, g);
    }
    void newNode(int &x, int v, int fa) {
         x = ++top;
         sz[x] = 1;
         pre[x] = fa;
         L = R = 0;
         col[x] = -1;
         ls[x] = rs[x] = ms[x] = val[x] = v;
    }
    void down(int x) {
    	if(~col[x]) {
    		col[L] = col[R] = val[L] = val[R] = col[x];
    		ls[L] = rs[L] = ms[L] = col[x] * sz[L];
    		ls[R] = rs[R] = ms[R] = col[x] * sz[R];
    		col[x] = -1;
    	}
    }

    void up(int x) {
        sz[x] = sz[L] + sz[R] + 1;
        ls[x] = ls[L];
        rs[x] = rs[R];
        ms[x] = max(ms[L], ms[R]);
        if(val[x]) {
        	ms[x] = max(ms[x], rs[L]+1+ls[R]);
        	if(ls[x] == sz[L]) ls[x] += ls[R]+1;
        	if(rs[x] == sz[R]) rs[x] += rs[L]+1;
        }
    }
    void build(int &x, int l, int r, int fa) {
        if(l > r) return;
        int m = (l + r) >> 1;
        newNode(x, 1, fa);
        build(L, l, m-1, x);
        build(R, m+1, r, x);
        up(x);
    }

    void init(int n) {
        top = 0;
        newNode(root, 0, 0);
        newNode(ch[root][1], 0, root);
        build(KT, 0, n-1, ch[root][1]);
        up(ch[root][1]); up(root);
    }
    void update(int l, int r, int c) {
        rto(l-1, 0);
        rto(r+1, root);
        col[KT] = val[KT] = c;
        ls[KT] = rs[KT] = ms[KT] = c*sz[KT];
        up(ch[root][1]);
        up(root);
    }
    int find(int x, int k, int pos) {	//找连续的空位的首位置
    	down(x);
    	if(ms[L] >= k) return find(L, k, pos);
    	pos += sz[L];
    	if(val[x] && rs[L]+ls[R]+1 >= k) return pos - rs[L];
    	return find(R, k, pos+1);
    }
}spt;
vector vec;
int main() {
	char op[22];
	int j, m, x;
	while (~scanf("%d%d", &n, &m)) {
		spt.init(n);
		vec.clear();
		while (m--) {
			scanf("%s", op);
			if (op[0] == 'R') {
				vec.clear();
				puts("Reset Now");
				spt.update(1, n, 1);
				continue;
			}
			scanf("%d", &x);
			if (op[0] == 'N') {
				if (spt.ms[spt.root] < x) {
					puts("Reject New");
					continue;
				}
				int l = spt.find(spt.root, x, 0);
				printf("New at %d\n", l);
				int r = l + x - 1;
				spt.update(l, r, 0);
				pii tp = mp(l, r);
				j = lower_bound(vec.begin(), vec.end(), tp) - vec.begin();
				vec.insert(vec.begin() + j, tp);
			} else if (op[0] == 'G') {
				if ((int) vec.size() < x)
					puts("Reject Get");
				else
					printf("Get at %d\n", vec[x - 1].first);
			} else if (op[0] == 'F') {

				j = upper_bound(vec.begin(), vec.end(), mp(x, n + 3))
						- vec.begin() - 1;
				if (j == -1 || vec[j].first > x || vec[j].second < x)
					puts("Reject Free");
				else {

					printf("Free from %d to %d\n", vec[j].first, vec[j].second);
					spt.update(vec[j].first, vec[j].second, 1);
					vec.erase(vec.begin() + j);
				}
			}
		}
		puts("");
	}
	return 0;
}
#include 
#include 
#include 
#include 
using namespace std;
const int maxn = 50006;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define ls rt<<1
#define rs rt<<1|1
#define Mid int m = (l+r) >> 1
#define mp make_pair
typedef pair pii;
int n;
struct segTree {
    int lsum[maxn<<2], rsum[maxn<<2], msum[maxn<<2];
    int col[maxn<<2];
    inline void up(int l, int r, int rt) {
        msum[rt] = max(msum[ls], msum[rs]);
        msum[rt] = max(msum[rt],  rsum[ls] + lsum[rs]);
        Mid;
        lsum[rt] = lsum[ls];
        if (lsum[ls] == m - l + 1) lsum[rt] += lsum[rs];
        rsum[rt] = rsum[rs];
        if (lsum[rs] == r - m) rsum[rt] += rsum[ls];
    }
    inline void down(int l, int r, int rt) {
        if (~col[rt]) {
            col[ls] = col[rs] = col[rt];
            Mid;
            lsum[ls] = rsum[ls] = msum[ls] = col[rt] * (m - l + 1);

            lsum[rs] = rsum[rs] = msum[rs] = col[rt]* (r - m );
            col[rt] = -1;
        }
    }
    void build(int l = 1, int r = n, int rt = 1) {
        lsum[rt] = rsum[rt] = msum[rt] = r - l + 1;
        col[rt] = -1;
        if (l == r)
            return;
        Mid;
        build(lson);
        build(rson);
  //      up(l, r, rt);
    }
    void update(int L, int R, int v, int l = 1, int r = n, int rt = 1) {
        if (L <= l && r <= R) {
            col[rt] = v;
            rsum[rt] = lsum[rt] = msum[rt] = v * (r - l + 1);
            return;
        }
        Mid;
        down(l, r, rt);
        if (L <= m)
            update(L, R, v, lson);
        if (R > m)
            update(L, R, v, rson);
        up(l, r, rt);
    }
    int find(int x, int l = 1, int r = n, int rt = 1) {
        if (l == r)
            return l;
        Mid;
        down(l, r, rt);
        if (msum[ls] >= x)
            return find(x, lson);
        else if (rsum[ls] + lsum[rs] >= x)
            return m - rsum[ls] + 1;
        else
       return find(x, rson);
    }
} tree;
vector vec;
int main() {
    char op[22];
    int j, m, x;
    wh
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇核心动画中的动画组和转场动画 下一篇hdu 1054 Strategic Game(tree dp..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·怎样用 Python 写一 (2025-12-27 02:49:19)
·如何学习python数据 (2025-12-27 02:49:16)
·想要自学数据分析, (2025-12-27 02:49:14)
·Java 集合框架 - 菜 (2025-12-27 02:19:36)
·Java集合框架最全详 (2025-12-27 02:19:33)