• 线段树专辑—— hdu 2871 Memory Control


    http://acm.hdu.edu.cn/showproblem.php?pid=2871

    求解区间内连续空闲区间!

    题目有四种操作:

    1、New X,查找一个有x连续空间的区间,并返回区间的首位置,要求答案尽量考前。如果找不到x的连续空间,则返回“Reject New”。

    这是最基础的线段树操作。和pku 3667、hdu 1540一样的过程

    2、Free X,释放第x个记忆片段,所谓第x个第一片段,指的是剩余的记忆片段中,相对来说第x次 “New x” 的结果。将其区间跟新即可,关于这道题,记录第x个记忆片段是需要技巧的,直接用数组模拟无疑是找死。纠结了许久以后,还是看了别人的结题报告,人家都是用的vector容器,不太会,学习了一下。。。

    3、Get x,输出第X个记忆片段的首位置

    4、Reset,重新置0,将线段树整体跟新一下即可

    介绍一下利用vector容器如何实现二分时间的查找!

    首先,定义一个记录左右端点结构的vector容器

    struct NODE { int l; int r; }; vector<NODE>mery;

    接下来,定义该结构的排序函数

    bool cmp(const NODE &a,const NODE &b) { return a.l<b.l; }

    假设我们已经有了[1,3]、[7,8]、[11,15]三个记忆片段,并且他们已经储存在mery中了。现在我们要插入记忆片段[4,6],那么我们该将它插入到哪个位置呢?

    从肉眼看,我们简单的看到应该插入到[1,3]和[7,8]中间,那么该如何处理呢?

    首先定义一个关于NODE的vector的迭代器(俗称指针) 

    vector<NODE>::iterator it;

    接下来调用一个叫做 upper_bound()的函数,这个函数是一个类函数,各种数据都能处理,它的作用是在一个数组中,给它一个x,它将返回第一个比x大的数的位置所在!

    it=upper_bound(mery.begin(),mery.end(),b,cmp);  //从开始到结尾根据cmp原则查找第一个比b大的数据所在的位置

    这样,it 便保存着[1,3]、[7,8]中间那个地方的位置了,最后我们只需要 mery.insert(it,b); 这就把[4,6]插入到了对应的位置    //b所代表的就是[4,6]


    最后再介绍一下如何删除指定位置的数据:

    首先依然是利用upper_bound()函数找到某个数据在vector中的位置,由于该函数返回的是第一个大于该数据的地址,所以记得将结果减一即可!

    it=upper_bound(mery.begin(),mery.end(),b,cmp);

    int temp=it-mery.begin()-1;  //指针减指针得到一个常数值,该值既是下标,再减一得到准确地址

    mery.erase(mery.begin()+temp); 


    View Code
      1 #include<iostream>
    2 #include<string>
    3 #include<vector>
    4 #include<algorithm>
    5 using namespace std;
    6
    7 struct node
    8 {
    9 int l;
    10 int r;
    11 int cover;
    12 int lval;
    13 int rval;
    14 int maxval;
    15 };
    16
    17 node tree[250000];
    18 int n,m;
    19 int v[50000];
    20
    21 struct NODE
    22 {
    23 int l;
    24 int r;
    25 };
    26 vector<NODE>mery;
    27
    28 int max(int a,int b)
    29 {
    30 return a>b?a:b;
    31 }
    32
    33 bool cmp(const NODE &a,const NODE &b)
    34 {
    35 return a.l<b.l;
    36 }
    37
    38 void build(int i,int l,int r)
    39 {
    40 tree[i].l=l;
    41 tree[i].r=r;
    42 tree[i].cover=0;
    43 tree[i].lval=tree[i].rval=tree[i].maxval=(r-l+1);
    44 if(l==r)
    45 return;
    46 int mid=(l+r)/2;
    47 build(2*i,l,mid);
    48 build(2*i+1,mid+1,r);
    49 }
    50
    51 void fun(int i,int w)
    52 {
    53 if(w==0)
    54 tree[i].rval=tree[i].lval=tree[i].maxval=(tree[i].r-tree[i].l+1);
    55 else
    56 tree[i].rval=tree[i].lval=tree[i].maxval=0;
    57 }
    58
    59 void updata(int i,int l,int r,int w)
    60 {
    61 if(tree[i].l>r || tree[i].r<l)
    62 return;
    63 if(tree[i].l>=l && tree[i].r<=r)
    64 {
    65 tree[i].cover=w;
    66 fun(i,w);
    67 return;
    68 }
    69 if(tree[i].cover!=-1)
    70 {
    71 tree[2*i].cover=tree[2*i+1].cover=tree[i].cover;
    72 fun(2*i,tree[i].cover);
    73 fun(2*i+1,tree[i].cover);
    74 }
    75 updata(2*i,l,r,w);
    76 updata(2*i+1,l,r,w);
    77 if(tree[2*i].cover==0 && tree[2*i+1].cover==0)
    78 tree[i].cover=0;
    79 else if(tree[2*i].cover==1 && tree[2*i+1].cover==1)
    80 tree[i].cover=1;
    81 else
    82 tree[i].cover=-1;
    83 tree[i].lval=tree[2*i].lval+(tree[2*i].cover==0?tree[2*i+1].lval:0);
    84 tree[i].rval=tree[2*i+1].rval+(tree[2*i+1].cover==0?tree[2*i].rval:0);
    85 tree[i].maxval=max(max(tree[2*i].maxval,tree[2*i+1].maxval),(tree[2*i].rval+tree[2*i+1].lval));
    86 }
    87
    88 int query(int i,int w)
    89 {
    90 if(tree[i].cover==0 && tree[i].lval>=w)
    91 return tree[i].l;
    92 else if(tree[i].cover==1)
    93 return 0;
    94 else if(tree[i].cover==-1)
    95 {
    96 if(tree[2*i].maxval>=w)
    97 return query(2*i,w);
    98 else if(tree[2*i].rval+tree[2*i+1].lval>=w)
    99 {
    100 return tree[2*i].r-tree[2*i].rval+1;
    101 }
    102 else if(tree[2*i+1].maxval>=w)
    103 return query(2*i+1,w);
    104 }
    105 return 0;
    106 }
    107
    108
    109
    110 int main()
    111 {
    112 int i,a,ans;
    113 char str[6];
    114 NODE b;
    115 //freopen("in.txt","r",stdin);
    116 while(scanf("%d%d",&n,&m)==2)
    117 {
    118 build(1,1,n);
    119 mery.clear();
    120 for(i=0;i<m;i++)
    121 {
    122 scanf("%*c");
    123 scanf("%s",str);
    124 if(str[0]=='R')
    125 {
    126 updata(1,1,n,0);
    127 printf("Reset Now\n");
    128 mery.clear();
    129 }
    130 else if(str[0]=='N')
    131 {
    132 scanf("%d",&a);
    133 ans=query(1,a);
    134 if(ans>0)
    135 {
    136 printf("New at %d\n",ans);
    137 updata(1,ans,ans+a-1,1);
    138 b.l=ans;b.r=ans+a-1;
    139 vector<NODE>::iterator it;
    140 it=upper_bound(mery.begin(),mery.end(),b,cmp);
    141 mery.insert(it,b);
    142 }
    143 else
    144 {
    145 printf("Reject New\n");
    146 }
    147 }
    148 else if(str[0]=='F')
    149 {
    150 scanf("%d",&a);
    151 b.l=a;
    152 b.r=a;
    153 vector<NODE>::iterator it;
    154 it=upper_bound(mery.begin(),mery.end(),b,cmp);
    155 int temp=it-mery.begin()-1;
    156 if(temp==-1 || mery[temp].r<a)
    157 printf("Reject Free\n");
    158 else
    159 {
    160 printf("Free from %d to %d\n",mery[temp].l,mery[temp].r);
    161 updata(1,mery[temp].l,mery[temp].r,0);
    162 mery.erase(mery.begin()+temp);
    163 }
    164 }
    165 else if(str[0]=='G')
    166 {
    167 scanf("%d",&a);
    168 if(a>mery.size())
    169 {
    170 printf("Reject Get\n");
    171 }
    172 else
    173 {
    174 printf("Get at %d\n",mery[a-1].l);
    175 }
    176 }
    177 }
    178 printf("\n");
    179 }
    180 return 0;
    181 }



  • 相关阅读:
    从开发者角色到产品角色转换
    前端开发做什么?
    最近的前端开发认知总结
    最近的Vue知识总结
    计算机网络
    javascript 字符串加密的几种方法
    JSON数据解析
    JAVA 自定义状态码
    JAVA jdbc获取数据库连接
    JAVA通过md5方法进行加密
  • 原文地址:https://www.cnblogs.com/ka200812/p/2246448.html
Copyright © 2020-2023  润新知