zoukankan      html  css  js  c++  java
  • hdu 2871 线段树(各种操作)

    Memory Control

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 5913    Accepted Submission(s): 1380

    Problem Description
    Memory units are numbered from 1 up to N.
    A sequence of memory units is called a memory block. 
    The memory control system we consider now has four kinds of operations:
    1.  Reset Reset all memory units free.
    2.  New x Allocate a memory block consisted of x continuous free memory units with the least start number
    3.  Free x Release the memory block which includes unit x
    4.  Get x Return the start number of the xth memory block(Note that we count the memory blocks allocated from left to right)
    Where 1<=x<=N.You are request to find out the output for M operations. 
     
    Input
    Input contains multiple cases.
    Each test case starts with two integer N,M(1<=N,M<=50000) ,indicating that there are N units of memory and M operations.
    Follow by M lines,each line contains one operation as describe above.
     
    Output
    For each “Reset” operation, output “Reset Now”.
    For each “New” operation, if it’s possible to allocate a memory block,
    output “New at A”,where Ais the least start number,otherwise output “Reject New”.
    For each “Free” operation, if it’s possible to find a memory block occupy unit x,
    output “Free from A to B”,where A and B refer to the start and end number of the memory block,otherwise output “Reject Free”.
    For each “Get” operation, if it’s possible to find the xth memory blocks,
    output “Get at A”,where A is its start number,otherwise output “Reject Get”.
    Output one blank line after each test case.
     
    Sample Input
    6 10
    New 2
    New 5
    New 2
    New 2
    Free 3
    Get 1
    Get 2
    Get 3
    Free 3
    Reset
    Sample Output
    New at 1
    Reject New
    New at 3
    New at 5 
    Free from 3 to 4
    Get at 1
    Get at 5
    Reject Get
    Reject Free
    Reset Now
    /*
    hdu 2871 线段树(各种操作)
    
    New x:从1开始找到一个长度x空白区间来分配内存
    Free x:释放x所在连续区间的内存 并输出左右端点
    Get x:获得第x个区间的左端点
    reset:释放全部的内存
    
    如果对一个区间分配了内存则置为1,空白处全是0
    1.对于New操作需要的便是0的最大连续长度 可通过ls,rs,ms来求,先判断区间是否能放下
    能则找出它的左端点即可
    2.然后是Free,即1的区间。我们可以用from,to来记录一个区间的左右端点,然后通过
    push_down下放到单点.所以只需要找出x点对应的节点编号i即可
    3.因为求的是第x个区间,所以开始用num求的时候错了好几次。发现可以把区间左端点
    标记为1.但是在实现的时候忘记了判断当前位置是否是要更新区间的左端点,卒!
    if(tree[i].l == l)
        tree[i].num = 1;
    4.对于reset,把区间全部更新为0即可
    
    求单点所在区间左右端点+最长连续区间的运用+求第k个区间
    
    hhh-2016-04-02 17:48:33
    */
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define lson  (i<<1)
    #define rson  ((i<<1)|1)
    typedef long long ll;
    const int maxn = 50050;
    
    struct node
    {
        int l,r;
        int ls,ms,rs;   //记录0的连续区间
        int num,same;
        int from,to;    //记录1的左右端点
        int mid()
        {
            return (l+r)>>1;
        }
        int len()
        {
            return (r-l+1);
        }
    } tree[maxn<<2];
    
    void push_up(int i)
    {
        tree[i].ls = tree[lson].ls,tree[i].rs= tree[rson].rs;
        if(tree[i].ls == tree[lson].len())
            tree[i].ls += tree[rson].ls;
        if(tree[i].rs == tree[rson].len())
            tree[i].rs += tree[lson].rs;
        tree[i].ms = max(tree[lson].ms,tree[rson].ms);
        tree[i].ms = max(tree[i].ms,tree[lson].rs + tree[rson].ls);
    
        tree[i].num = tree[lson].num + tree[rson].num;
    }
    
    void ini(int i,int val)
    {
        tree[i].ls=tree[i].rs=tree[i].ms=val;
    }
    
    void build(int i,int l,int r)
    {
        tree[i].l = l,tree[i].r = r;
        tree[i].same =tree[i].from = tree[i].to = -1;
        tree[i].num = 0;
        if(l == r)
        {
            ini(i,1);
            return ;
        }
        int mid = (l+r)>>1;
        build(lson,l,mid);
        build(rson,mid+1,r);
        push_up(i);
    }
    
    void push_down(int i)
    {
        if(tree[i].same != -1)
        {
            tree[lson].same = tree[i].same;
            tree[rson].same = tree[i].same;
            tree[lson].from = tree[rson].from = tree[i].from;
            if(tree[i].num != -1)
            {
                tree[lson].num = tree[i].num;
                tree[rson].num = 0;
            }
            tree[lson].to = tree[rson].to = tree[i].to;
            ini(lson,(!tree[i].same)*tree[lson].len());
            ini(rson,(!tree[i].same)*tree[rson].len());
            tree[i].same = -1;
        }
    
    }
    
    void update(int i,int l,int r,int val)
    {
        if(tree[i].l >= l && tree[i].r <= r)
        {
            tree[i].same = val;
            if(val)
            {
                if(tree[i].l == l)
                tree[i].num = 1;
                tree[i].from = l;
                tree[i].to = r;
                ini(i,0);
            }
            else
            {
                if(tree[i].l == l)
                tree[i].num = 0;
                tree[i].from = tree[i].to = -1;
                ini(i,tree[i].len());
            }
            return ;
        }
        push_down(i);
        int mid = tree[i].mid();
        if(l <= mid)
            update(lson,l,r,val);
        if(r > mid)
            update(rson,l,r,val);
        push_up(i);
        return ;
    }
    
    int New(int i,int len)
    {
        if(tree[i].l == tree[i].r)
        {
            return tree[i].l;
        }
        int mid = tree[i].mid();
        push_down(i);
        if(tree[lson].ms >= len)
            return New(lson,len);
        else if(tree[lson].rs + tree[rson].ls >= len)
            return mid-tree[lson].rs+1;
        else
            return New(rson,len);
    }
    
    int Free(int i,int k)
    {
        if(tree[i].l == tree[i].r)
            return i;
        push_down(i);
        int mid = tree[i].mid();
        if(k <= mid)
            return Free(lson,k);
        else
            return Free(rson,k);
    }
    
    int Get(int i,int k)
    {
        if(tree[i].l == tree[i].r)
            return tree[i].l;
        push_down(i);
        if(tree[lson].num >= k)
            return Get(lson,k);
        else
            return Get(rson,k-tree[lson].num);
    }
    
    char op[10];
    
    int main()
    {
        int n,m;
        while(scanf("%d%d",&n,&m) != EOF)
        {
            build(1,1,n);
            int x;
            while(m--)
            {
                scanf("%s",op);
                if(op[0] == 'N')
                {
                    scanf("%d",&x);
    
                    if(tree[1].ms >= x)
                    {
                        int l = New(1,x);
                        printf("New at %d
    ",l);
                        update(1,l,l+x-1,1);
                    }
                    else
                        printf("Reject New
    ");
    
                }
                else if(op[0] == 'F')
                {
                    scanf("%d",&x);
                    int t = Free(1,x);
                    if(tree[t].from == -1)
                        printf("Reject Free
    ");
                    else
                    {
                        printf("Free from %d to %d
    ",tree[t].from,tree[t].to);
                        update(1,tree[t].from,tree[t].to,0);
                    }
                }
                else if(op[0] == 'G')
                {
                    scanf("%d",&x);
                    if(tree[1].num >= x)
                        printf("Get at %d
    ",Get(1,x));
                    else
                        printf("Reject Get
    ");
                }
                else if(op[0] == 'R')
                {
                    update(1,1,n,0);
                    printf("Reset Now
    ");
                }
            }
            printf("
    ");
        }
        return 0;
    }
    

      


  • 相关阅读:
    Javascript作用域研究(with)
    Javascript判断object还是list/array的类型(包含javascript的数据类型研究)
    Javascript两个感叹号的用法(!!)
    Javascript中两个等于号和三个等于号的区别(==/===)
    IIS配置MP3/MP4/OGG/flv等资源文件访问
    生成GUID唯一值的方法汇总(dotnet/javascript/sqlserver)
    记录一次:微信支付申请时,网站不通过/统一驳回的问题解决方法
    C# 扩展系统类方法
    Javascript获取div真实高度
    Jquery获取offsetHeight
  • 原文地址:https://www.cnblogs.com/Przz/p/5409564.html
Copyright © 2011-2022 走看看