zoukankan      html  css  js  c++  java
  • HDU 2871 Memory Control

    裸线段树区间合并,一开始没注意题目细节结果搞麻烦了……

    给你四种操作,每种操作按它的要求输出结果。

    1.  Reset Reset all memory units free. 

    Reset 释放所有的内存

    2.  New x Allocate a memory block consisted of x continuous free memory units with the least start number

    New x   申请一个包含x个连续内存单元的内存块,起始地址编号最小

    3.  Free x Release the memory block which includes unit x

    Free x  释放包含地址x的内存块

    (这个地方有个注意点可以从样例中得到,就是说如果我先申请了内存块1-2,后申请了内存块3-4,虽然1-4此时都被申请了,但1-4并不属于一个连续的内存块,因为它不是被一次申请的。如果查询4所在的内存块的起始地址,应当输出3,而不是1 )

    4.  Get x Return the start number of the xth memory block(Note that we count the memory blocks allocated from left to right)

    Get x 返回第x个内存块的起始地址(假定我们将内存块从左到右编号)

    因为把题意的细节理解的有问题,所以一开始我的线段树不只是记录了连续的空余区间长度,还把连续被申请的区间长度也记录了,事实证明这是完全没必要。然后就去掉了。

    还有一个地方是用一个vector来记录一下已经申请的内存块,因为要用二分查找,所以在向vector中插入元素时应注意维护一下它的有序性。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <algorithm>
      5 #include <vector>
      6 
      7 using namespace std;
      8 
      9 #define lc rt << 1
     10 #define rc rt << 1 | 1
     11 #define lson l, m, rt << 1
     12 #define rson m + 1, r, rt << 1 | 1
     13 
     14 const int MAXN = 50002;
     15 
     16 struct node
     17 {
     18     int st, ed;
     19     node(){}
     20     node( int _st, int _ed ) : st( _st ), ed( _ed ) { }
     21 };
     22 
     23 vector<node> blocks;
     24 
     25 int N, Q;
     26 int len[ MAXN << 2 ];    //空闲区最长连续长度
     27 
     28 int Llen[ MAXN << 2 ];   //左端空闲区长度
     29 int Rlen[ MAXN << 2 ];   //右端空闲区长度
     30 
     31 int flag[ MAXN << 2 ];   //0 释放  -1  无标记   1 占用
     32 
     33 bool lbd[ MAXN << 2 ];   //左端点是否空闲
     34 bool rbd[ MAXN << 2 ];   //右端点是否空闲
     35 
     36 void chuli( int op, int rt, int l, int r )
     37 {
     38     if ( op == 0 )
     39         Llen[rt] = Rlen[rt] = len[rt] = r - l + 1;
     40     else
     41         Llen[rt] = Rlen[rt] = len[rt] = 0;
     42 
     43     lbd[rt] = rbd[rt] = op ^ 1;
     44     return;
     45 }
     46 
     47 void PushDown( int rt, int l, int r, int m )
     48 {
     49     if ( flag[rt] != -1 )
     50     {
     51         flag[lc] = flag[rc] = flag[rt];
     52         chuli( flag[lc], lc, l, m );
     53         chuli( flag[rc], rc, m + 1, r );
     54         flag[rt] = -1;
     55     }
     56     return;
     57 }
     58 
     59 void PushUp( int rt, int l, int r, int m )
     60 {
     61     lbd[rt] = lbd[lc];
     62     rbd[rt] = rbd[rc];
     63 
     64     Llen[rt] = Llen[lc];
     65     Rlen[rt] = Rlen[rc];
     66 
     67     if ( Llen[lc] == m - l + 1 ) Llen[rt] += Llen[rc];
     68     if ( Rlen[rc] == r - m )     Rlen[rt] += Rlen[lc];
     69 
     70     len[rt] = max( len[lc], len[rc] );
     71     if ( lbd[rc] && rbd[lc] ) len[rt] = max( len[rt], Llen[rc] + Rlen[lc] );
     72 
     73     return;
     74 }
     75 
     76 void build( int l, int r, int rt )
     77 {
     78     flag[rt] = -1;
     79     if ( l == r )
     80     {
     81         len[rt] = Llen[rt] = Rlen[rt] = 1;
     82         lbd[rt] = rbd[rt] = true;
     83         return;
     84     }
     85 
     86     int m = ( l + r ) >> 1;
     87     build( lson );
     88     build( rson );
     89     PushUp( rt, l, r, m );
     90 
     91     return;
     92 }
     93 
     94 void Update( int L, int R, int op, int l, int r, int rt )
     95 {
     96     int m = ( l + r ) >> 1;
     97     if ( L <= l && r <= R )
     98     {
     99         flag[rt] = op;
    100         chuli( op, rt, l, r );
    101         return;
    102     }
    103     PushDown( rt, l, r, m );
    104 
    105     if ( L <= m ) Update( L, R, op, lson );
    106     if ( R > m )  Update( L, R, op, rson );
    107 
    108     PushUp( rt, l, r, m );
    109 
    110     return;
    111 }
    112 
    113 int Query( int a, int op, int l, int r, int rt )  //op代表查询空闲区间还是占用区间
    114 {
    115     int m = ( l + r ) >> 1;
    116 
    117     if ( l == r )
    118     {
    119         if ( len[rt] == a ) return l;
    120         else return 0;
    121     }
    122 
    123     PushDown( rt, l, r, m );
    124 
    125     if ( len[lc] >= a ) return Query( a, op, lson );
    126     else if ( Rlen[lc] + Llen[rc] >= a ) return m - Rlen[lc] + 1;
    127     else if ( len[rc] >= a ) return Query( a, op, rson );
    128     else return 0;
    129 }
    130 
    131 int BiSearch( int tar )
    132 {
    133     int low = 0, high = blocks.size() - 1, mid;
    134     while ( low <= high )
    135     {
    136         mid = ( low + high ) >> 1;
    137         if ( blocks[mid].st <= tar ) low = mid + 1;
    138         else high = mid - 1;
    139     }
    140     return low;
    141 }
    142 
    143 int main()
    144 {
    145     while ( ~scanf( "%d%d", &N, &Q ) )
    146     {
    147         build( 1, N, 1 );
    148         blocks.clear();
    149         while ( Q-- )
    150         {
    151             char oper[10];
    152             int a, idx;
    153             scanf( "%s", oper );
    154             if ( oper[0] == 'R' )
    155             {
    156                 Update( 1, N, 0, 1, N, 1 );
    157                 blocks.clear();
    158                 puts("Reset Now");
    159             }
    160             else
    161             {
    162                 scanf( "%d", &a );
    163                 switch( oper[0] )
    164                 {
    165                     case 'N':
    166                     if ( len[1] < a ) puts("Reject New");
    167                     else
    168                     {
    169                         int st = Query( a, 0, 1, N, 1 );
    170                         printf( "New at %d\n", st );
    171                         idx = BiSearch( st );
    172                         blocks.insert( blocks.begin() + idx, node( st, st + a - 1 ) );
    173                         Update( st, st + a - 1, 1, 1, N, 1 );
    174                     }
    175                     break;
    176 
    177                     case 'F':
    178                     idx = BiSearch(a) - 1;
    179                     if ( idx == -1 || a > blocks[idx].ed ) puts("Reject Free");
    180                     else
    181                     {
    182                         printf( "Free from %d to %d\n", blocks[idx].st, blocks[idx].ed );
    183                         Update( blocks[idx].st, blocks[idx].ed, 0, 1, N, 1 );
    184                         blocks.erase( blocks.begin() + idx, blocks.begin() + idx + 1 );
    185                     }
    186                     break;
    187 
    188                     case 'G':
    189                     --a;
    190                     if ( a >= (int)blocks.size() ) puts("Reject Get");
    191                     else printf( "Get at %d\n", blocks[a].st );
    192                     break;
    193                 }
    194             }
    195         }
    196         puts("");
    197     }
    198     return 0;
    199 }
  • 相关阅读:
    精细化python 类的内置属性
    python操作excel
    ghost linux
    Linux dd 命令
    Ubantu 使用root登陆的方法
    NSIS Error: "Error writing temporary file. Make sure your temp folder is valid
    error writing temporary file。make sure your temp folder is valid 问题已解决
    安卓电池状态监听
    Android源码下载
    vim插件详细安装过程
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/3091867.html
Copyright © 2011-2022 走看看