zoukankan      html  css  js  c++  java
  • 51Nod1207 内存管理

    题目看这里

    这么好玩的数据结构题肯定是要来做一做啦

    考虑splay-

    显然用一个节点去维护一个连续的内存块,每次申请内存就找一块尽可能前的,释放就找一个有相交的并合并,没有则新建节点

    splay一打还是错落百出,不过效率还是可以的,跑了第一和map一样快

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define N 100010
    #define son(x) (s[f[x]][1]==x)
    using namespace std;
    int f[N],s[N][2],sz[N],v[N],l[N],t[N];
    int n,m,cnt=0,rt=0;
    inline int newnode(int p,int len){
        ++cnt; sz[cnt]=1;
        v[cnt]=p; l[cnt]=t[cnt]=len;
        return cnt;
    }
    inline int ps(int x){
        sz[x]=sz[s[x][0]]+sz[s[x][1]]+1;
        t[x]=max(l[x],max(t[s[x][0]],t[s[x][1]]));
    }
    inline void rot(int x){
        int p=f[x],g=f[p],d=son(x);
        s[p][d]=s[x][!d]; f[s[p][d]]=p;
        s[x][!d]=p; f[p]=x; f[x]=g;
        if(g) s[g][p==s[g][1]]=x; ps(p); ps(x);
    }
    inline void splay(int x,int r=0){
        for(int p;(p=f[x])!=r;rot(x))
            if(f[p]!=r && son(x)==son(p)) rot(p);
        if(!r) rt=x;
    }
    inline int select(int k,int x=rt){
        for(int w;;){
            w=sz[s[x][0]]+1;
            if(w==k) return x;
            if(k<w) x=s[x][0];
            else k-=w,x=s[x][1];
        }
    }
    inline int rank(int x){
        int r=sz[s[x][0]]+1;
        for(;x;x=f[x])
            if(son(x)) r+=sz[s[f[x]][0]]+1;
        return r;
    }
    inline int merge(int x,int y){
        if(x&&y){
            y=select(1,y);
            splay(y,rt);
            s[y][0]=x; f[x]=y; ps(y);
            return y;
        } return x+y;
    }
    inline void insert(int p,int len){
        if(!rt) { rt=newnode(p,len); return; }
        for(int x=rt,d;;){
            d=(p>=v[x]);
            if(!s[x][d]){
                s[x][d]=newnode(p,len);
                f[cnt]=x; splay(cnt); break;
            } else x=s[x][d];
        }
    }
    inline void link(int x,int y){
        l[x]=max(l[x],v[y]+l[y]-v[x]);
    }
    int main(){
        scanf("%d%d",&n,&m);
        rt=newnode(0,n);
        for(int o,x,y,z;m--;){
            scanf("%d%d",&o,&x);
            if(o==1){
                if(t[rt]<x) puts("-1");
                else{
                    y=x; x=rt;
                    for(;;)
                        if(t[s[x][0]]>=y) x=s[x][0];
                        else if(l[x]>=y) break; else x=s[x][1];
                    printf("%d
    ",v[x]);
                    splay(x);
                    l[x]-=y; v[x]+=y; ps(x);
                    if(l[x]==0) rt=merge(s[x][0],s[x][1]);
                }
            } else {
                scanf("%d",&y);
                o=x; x=rt; z=0;
                for(;x;)
                    if(v[x]+l[x]>=o) z=x,x=s[x][0];
                    else x=s[x][1];
                if(!z||v[z]>o){ insert(o,y); z=rt; }
                x=z; z=rank(x); splay(x); l[x]+=max(0,(o+y)-(v[x]+l[x]));
                o+=y; 
                for(;;){
                    if(z==sz[x]) break;
                    splay(select(z+1),rt); y=s[x][1];
                    if(v[y]>o) break;
                    else{ link(x,y); s[x][1]=s[y][1]; f[s[y][1]]=x; ps(x); }
                }
                ps(x);
            }
        }
    }


  • 相关阅读:
    Java程序,猜大小游戏
    Java程序,取随机数的两种实现方法
    用Java程序判断是否是闰年
    Python学习-基础篇17 Django-进阶
    Python学习-基础篇16 Django-Ajax、Cookie
    Python学习-基础篇15 Django-MTV
    Python学习-基础篇14 Web框架本质及第一个Django实例
    Python学习-基础篇13 前端知识之Bootstrap框架
    Python学习-基础篇12 前端知识之Javascript知识
    Python学习-基础篇11 前端知识之HTML内容
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/9477129.html
Copyright © 2011-2022 走看看