• hdu_2871_Memory Control(巨恶心线段树)


    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2871

    题意:给你一段内存,让你操作1:Reset:重置所有内存 2:New x:申请一块X大小的内存,返回内存最左边的开头,3:free x:释放包含x单元的内存块 4:Get x:取第X块的内存首地址

    题解:这题我写了一晚上,很恶心,显然用线段树维护,不过用一个Vector 来应对 free和get操作比较方便,线段树就只需要维护内存的连续长度和最大长度就行了,

    ll[rt]为该区段从左边开始的连续内存长度,rr[rt]为该区间从右边开始的连续内存长度,mlen[rt]为该区间最大的连续内存长度,只有这样维护才能在线段树中任意操作区间


     1 #include<cstdio>
     2 #include<vector>
     3 #include<algorithm>
     4 using namespace std;
     5 #define F(i,a,b) for(int i=a;i<=b;i++)
     6 #define root 1,n,1
     7 #define ls l,m,rt<<1
     8 #define rs m+1,r,rt<<1|1
     9 #define Max(a,b) ((a)>(b)?(a):(b))
    10 
    11 struct edge{
    12     int l,r;
    13     bool operator<(const edge &b)const{return l<b.l;}
    14 }s,e,tp;
    15 const int maxn=50010;
    16 int n,m,num,ll[maxn<<2],rr[maxn<<2],lazy[maxn<<2],mlen[maxn<<2];
    17 vector<edge>Q;
    18 
    19 inline void pup(int l,int r,int rt){
    20     int m=(l+r)>>1;
    21     mlen[rt]=Max(mlen[rt<<1],mlen[rt<<1|1]);
    22     mlen[rt]=Max(mlen[rt],rr[rt<<1]+ll[rt<<1|1]);
    23     ll[rt]=ll[rt<<1]+(ll[rt<<1]==m-l+1?ll[rt<<1|1]:0);
    24     rr[rt]=rr[rt<<1|1]+(rr[rt<<1|1]==r-m?rr[rt<<1]:0);
    25 }
    26 
    27 inline void pdown(int l,int r,int rt){
    28     if(lazy[rt]!=-1){
    29         lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
    30         int m=(l+r)>>1;
    31         mlen[rt<<1]=ll[rt<<1]=rr[rt<<1]=(lazy[rt]==0?m-l+1:0);
    32         mlen[rt<<1|1]=rr[rt<<1|1]=ll[rt<<1|1]=(lazy[rt]==0?r-m:0);
    33         lazy[rt]=-1;
    34     }
    35 }
    36 
    37 int New(int l,int r,int rt,int num){
    38     if(l==r)return l;
    39     int m=(l+r)>>1;
    40     pdown(l,r,rt);
    41     if(mlen[rt<<1]>=num)return New(ls,num);
    42     else if(rr[rt<<1]+ll[rt<<1|1]>=num)return m-rr[rt<<1]+1;
    43     else return New(rs,num);
    44 }
    45 
    46 void covr(int op,int L,int R,int l,int r,int rt){//op为0是释放内存,1为占用
    47     if(L<=l&&r<=R){
    48         lazy[rt]=op,ll[rt]=rr[rt]=mlen[rt]=(op==0?r-l+1:0);
    49         return;
    50     }
    51     pdown(l,r,rt);
    52     int m=(l+r)>>1;
    53     if(L<=m)covr(op,L,R,ls);
    54     if(R>m)covr(op,L,R,rs);
    55     pup(l,r,rt);
    56 }
    57 
    58 void reset(){Q.clear(),Q.push_back(s),Q.push_back(e);covr(0,1,n,root);}
    59 
    60 void insert(edge xx){
    61     int now=upper_bound(Q.begin(),Q.end(),xx)-Q.begin();
    62     Q.insert(Q.begin()+now,xx);
    63 }
    64 
    65 int main(){
    66     char op[20];s.l=0,s.r=0,e.l=100000,e.r=100000;
    67     while(~scanf("%d%d",&n,&m)){
    68         reset();
    69         while(m--){
    70             scanf("%s",op);
    71             if(op[0]!='R')scanf("%d",&num);
    72             if(op[0]=='N')if(mlen[1]<num)puts("Reject New");
    73             else{int x=New(root,num);printf("New at %d
    ",x),tp.l=x,tp.r=x+num-1,covr(1,tp.l,tp.r,root),insert(tp);}
    74             else if(op[0]=='F'){
    75                 tp.l=num,tp.r=num;
    76                 int now=upper_bound(Q.begin(),Q.end(),tp)-Q.begin()-1;
    77                 if(Q[now].l<=num&&Q[now].r>=num)
    78                     covr(0,Q[now].l,Q[now].r,root),printf("Free from %d to %d
    ",Q[now].l,Q[now].r),Q.erase(Q.begin()+now);
    79                 else puts("Reject Free");
    80             }else if(op[0]=='G'){
    81                 if(num>Q.size()-2)puts("Reject Get");
    82                 else printf("Get at %d
    ",Q[num].l);
    83             }else reset(),puts("Reset Now");
    84         }
    85         puts("");
    86     }
    87     return 0;
    88 }
    View Code




  • 相关阅读:
    mac下用xattr命令来删除文件的扩展属性
    使用vue.js实现checkbox的全选和多个的删除功能
    正则表达式匹配任意字符(包括换行符)的写法
    jQuery Mobile动态刷新页面样式
    jquery mobile各类标签的refresh
    jQuery .attr()和.removeAttr()方法操作元素属性示例
    jquery mobile各类组件刷新方法
    Apache PDFbox开发指南之PDF文档读取
    日期字符串解析--SimpleDateFormat严格限制日期转换setLenient(false)
    hdu5032 Always Cook Mushroom
  • 原文地址:https://www.cnblogs.com/bin-gege/p/5696133.html
Copyright © 2020-2023  润新知