zoukankan      html  css  js  c++  java
  • HDU2871 Memory Control 线段树区间合并

    题目大意为给定一段内存快,要求根据命令输出正确的答案。

    New x    申请长度为x的空白内存的首地址,如果不满足输出Reject New
    Free x    释放包含x节点的内存块,注意该内存块为一个New操作所确定的区域,即不必要将物理相邻的内存块视作一个内存块
    Get x     得到从左到右的第x个内存块 
    Reset     重置总区间

    针对这些要求,设定一棵线段树,每个节点保留左,右连续空白段,以及区间总长。这样便能够处理New命令,而Free以及Get命令则用vector保留,用二分搜索优化。

    代码如下:

    View Code
    #include <cstdio>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #define MAXN 50000
    using namespace std;

    struct
    {
    int l, r;
    int lmax, rmax, max, cover;
    }seg[MAXN*4];

    struct Node
    {
    int s, e;
    }info;

    void up(int f)
    {
    seg[f].lmax = seg[f<<1].lmax;
    seg[f].rmax = seg[f<<1|1].rmax;
    if (seg[f<<1].cover == 0)
    seg[f].lmax += seg[f<<1|1].lmax;
    if (seg[f<<1|1].cover == 0)
    seg[f].rmax += seg[f<<1].rmax;
    seg[f].max = max(seg[f<<1].max, seg[f<<1|1].max);
    seg[f].max = max(seg[f].max, seg[f<<1].rmax+seg[f<<1|1].lmax);
    if (seg[f<<1].cover == seg[f<<1|1].cover)
    seg[f].cover = seg[f<<1].cover;
    else
    seg[f].cover = -1;
    }

    void build(int f, int l, int r)
    {
    int mid = l+r >> 1;
    seg[f].l = l, seg[f].r = r;
    seg[f].lmax = seg[f].rmax = seg[f].max = r-l+1;
    seg[f].cover = 0;
    if (r > l)
    {
    build(f<<1, l, mid);
    build(f<<1|1, mid+1, r);
    }
    }

    void modify(int f, int l, int r, int val)
    {
    int mid = seg[f].l+seg[f].r >> 1;
    if (seg[f].l == l && r == seg[f].r)
    {
    seg[f].cover = val;
    if (val == 1) // 如果是占用命令
    seg[f].lmax = seg[f].rmax = seg[f].max = 0;
    else
    seg[f].lmax = seg[f].rmax = seg[f].max = r-l+1;
    }
    else if (seg[f].r > seg[f].l)
    {
    if (seg[f].cover == 0)
    { // lazy 操作 相当于格式化一般的向下更新
    seg[f<<1].cover = seg[f<<1|1].cover = 0;
    seg[f<<1].lmax = seg[f<<1].r-seg[f<<1].l+1;
    seg[f<<1].rmax = seg[f<<1].r-seg[f<<1].l+1;
    seg[f<<1].max = seg[f<<1].r-seg[f<<1].l+1;
    seg[f<<1|1].lmax = seg[f<<1|1].r-seg[f<<1|1].l+1;
    seg[f<<1|1].rmax = seg[f<<1|1].r-seg[f<<1|1].l+1;
    seg[f<<1|1].max = seg[f<<1|1].r-seg[f<<1|1].l+1;
    seg[f].cover = -1;
    }
    else if (seg[f].cover == 1)
    {
    seg[f<<1].cover = seg[f<<1|1].cover = 1;
    seg[f<<1].lmax = 0;
    seg[f<<1].rmax = 0;
    seg[f<<1].max = 0;
    seg[f<<1|1].lmax = 0;
    seg[f<<1|1].rmax = 0;
    seg[f<<1|1].max = 0;
    seg[f].cover = -1;
    }
    if (r <= mid)
    modify(f<<1, l, r, val);
    else if (l > mid)
    modify(f<<1|1, l, r, val);
    else
    {
    modify(f<<1, l, mid, val);
    modify(f<<1|1, mid+1, r, val);
    }
    up(f);
    }
    }

    int query(int f, int size)
    {
    int mid = seg[f].l+seg[f].r >> 1;
    if (seg[f].max < size)
    return 0;
    else if (seg[f].r > seg[f].l)
    {
    if (seg[f].lmax >= size)
    {
    return seg[f].l;
    }
    else if (seg[f<<1].max >= size)
    return query(f<<1, size);
    else if (seg[f<<1].rmax+seg[f<<1|1].lmax >= size)
    return seg[f<<1].r-seg[f<<1].rmax+1;
    else
    return query(f<<1|1, size);
    }
    }

    int bsearch(int pos, vector<Node>&v, int way)
    {
    int l = 0, r = v.size()-1;
    while (l <= r)
    {
    int mid = l+r >> 1;
    if (pos > v[mid].s)
    l = mid + 1;
    else if (pos < v[mid].s)
    r = mid - 1;
    else if (way == 1)
    return mid;
    }
    if (way == 0)
    return l;
    else
    return r;
    }

    int main()
    {
    int N, M, x, loc;
    char op[10];
    while (scanf("%d %d", &N, &M) == 2)
    {
    build(1, 1, N);
    vector<Node>v;
    vector<Node>::iterator it;
    while (M--)
    {
    scanf("%s", op);
    if (op[0] == 'R')
    {
    seg[1].lmax = seg[1].rmax = seg[1].max = N;
    seg[1].cover = 0;
    v.clear();
    puts("Reset Now");
    }
    else if (op[0] == 'N')
    {
    scanf("%d", &x);
    int pos = query(1, x);
    if (pos == 0)
    puts("Reject New");
    else
    {
    printf("New at %d\n", pos);
    modify(1, pos, pos+x-1, 1);
    it = v.begin()+bsearch(pos, v, 0);
    info.s = pos, info.e = pos+x-1;
    v.insert(it, info);
    }
    }
    else if (op[0] == 'F')
    {
    scanf("%d", &x);
    loc = bsearch(x, v, 1);
    if (loc == -1)
    puts("Reject Free");
    else
    {
    it = v.begin()+loc;
    if (x >= it->s && x <= it->e)
    {
    printf("Free from %d to %d\n", it->s, it->e);
    modify(1, it->s, it->e, 0);
    v.erase(it);
    }
    else
    puts("Reject Free");
    }
    }
    else
    {
    scanf("%d", &x);
    if (x > v.size())
    puts("Reject Get");
    else
    printf("Get at %d\n", v[x-1].s);
    }
    }
    puts("");
    }
    return 0;
    }



  • 相关阅读:
    文件上传---普通文件fileupload.jar和url文件httpUrlConnection
    HttpClient学习整理
    编写更少量的代码:使用apache commons工具类库
    多线程进阶
    多线程下HashMap的死循环问题
    线程本地变量ThreadLocal源码解读
    Eclipse工作常见问题总结
    Java集合---ConcurrentHashMap原理分析
    Java集合---Arrays类源码解析
    Java集合---LinkedList源码解析
  • 原文地址:https://www.cnblogs.com/Lyush/p/2384186.html
Copyright © 2011-2022 走看看