●赘述题目

四种操作:

○Reset:将整个内存序列清空。

○New a:在尽量靠左的位置新建一个长度为a的内存块,并输出改内存块起始位置。(各个内存块即使相邻也不会合并。。)

○Free a:将a点所在的内存块清空,并输出清空的内存区间的左右端点。

○Get a:输出从左往右数的第a个内存块的起始位置。

●题解

方法:Splay在线维护

(○本来想的将序列中的每个点看作Splay树中的一个节点,然后进行区间操作。。但似乎比较麻烦。。)

○正解(erge大佬提出的思路):考虑到每个内存块不会合并的性质,将每一个内存块看作Splay树中的一个节点,且中序遍历各个节点的顺序即对应内存序列中各个内存块的从左至右的顺序(如下图)(区间化点)。然后剩下便是Splay的单点操作。

○为方便一些操作,先就加入两个边界点。

●代码

(注意NEW(insert)函数啊,有点坑坑。。)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 50005
#define ls tr[k][0]
#define rs tr[k][1]
using namespace std;
int fa[MAXN],tr[MAXN][2];
int l[MAXN],r[MAXN],ll[MAXN],rr[MAXN],ma[MAXN],siz[MAXN];
int tot,root;
void pushup(int k)
{ll[k]=ls?ll[ls]:l[k]; rr[k]=rs?rr[rs]:r[k];ma[k]=max(max(ls?ma[ls]:0,rs?ma[rs]:0),max(ls?l[k]-rr[ls]-1:0,rs?ll[rs]-r[k]-1:0));siz[k]=1+(ls?siz[ls]:0)+(rs?siz[rs]:0);
}
void rotate(int x,int &k)
{int y=fa[x],z=fa[y];int l=tr[y][1]==x,r=1^l;if(y==k) k=x;else tr[z][tr[z][1]==y]=x;fa[tr[x][r]]=y; fa[y]=x; fa[x]=z;tr[y][l]=tr[x][r]; tr[x][r]=y;pushup(y);
}
void splay(int x,int &k)
{int y,z;while(x!=k){y=fa[x]; z=fa[y];if(y!=k) ((tr[z][0]==y)^(tr[y][0]==x)) ? rotate(x,k):rotate(y,k);rotate(x,k);}pushup(x);
}
int NEW(int &k,int last,int len,int fg,int sl)
{if(!k){k=++tot;fa[k]=last;l[k]=sl; r[k]=l[k]+len-1;tr[k][0]=tr[k][1]=0;splay(k,root);return l[root];} if(fg==0) return NEW(rs,k,len,0,r[k]+1);else if(fg==1) return NEW(ls,k,len,1,sl);else if(ls&&ma[ls]>=len)  return NEW(ls,k,len,-1,sl);else if(ls&&l[k]-rr[ls]-1>=len) return NEW(ls,k,len,0,r[k]+1);else if(rs&&ll[rs]-r[k]-1>=len) return NEW(rs,k,len,1,r[k]+1);else if(rs&&ma[rs]>=len) return NEW(rs,k,len,-1,sl);return 0;
}
int find(int k,int x)
{if(ll[ls]<=x&&x<=rr[ls]) return find(ls,x);else if(l[k]<=x&&x<=r[k]) return k;else if(ll[rs]<=x&&x<=rr[rs]) return find(rs,x);return 0;
}
int FREE(int x)
{int k=find(root,x);if(!k) return 0;splay(k,root);if(ls*rs==0) root=ls+rs,fa[root]=0;else{int p=rs;while(tr[p][0]) p=tr[p][0];tr[p][0]=ls;fa[ls]=p;root=rs;fa[root]=0;splay(ls,root);}return k;
}
int GET(int k,int x)
{if(siz[ls]>=x) return GET(ls,x); x-=siz[ls];if(x==1) return l[k]; x-=1;if(siz[rs]>=x) return GET(rs,x);return 0;
}
void pre(int n)
{root=1; tot=2;tr[1][0]=0; tr[1][1]=2; tr[2][0]=0; tr[2][1]=0;fa[2]=1;l[1]=r[1]=0; l[2]=r[2]=n+1;pushup(2); pushup(1);
}
int main()
{int n,m,a,b; char s[10]; while(~scanf("%d%d",&n,&m)){pre(n);while(m--){scanf(" %s",s);if(s[0]=='R') pre(n),printf("Reset Now\n");else if(s[0]=='N') scanf("%d",&a),1<=a&&a<=n?b=NEW(root,0,a,-1,-1):b=0,b?printf("New at %d\n",b):printf("Reject New\n");else if(s[0]=='F') scanf("%d",&a),1<=a&&a<=n?b=FREE(a):b=0,b?printf("Free from %d to %d\n",l[b],r[b]):printf("Reject Free\n");else if(s[0]=='G') scanf("%d",&a),siz[root]-2>=a?b=GET(root,a+1):b=0,b?printf("Get at %d\n",b):printf("Reject Get\n"); }printf("\n");}return 0;
}

转载于:https://www.cnblogs.com/zj75211/p/7251160.html

●HDU 2871 Memory Control(Splay)相关推荐

  1. hdu 2871 Memory Control(线段树)

    题目链接:hdu 2871 Memory Control 题目大意:模拟一个内存分配机制. Reset:重置,释放全部空间 New x:申请内存为x的空间,输出左地址 Free x:释放地址x所在的内 ...

  2. HDU - 2871 Memory Control(线段树+区间合并)好题!

    题目链接:点击查看 题目大意:给定n个内存和m个操作,分别是: New x:从内存编号1开始向右查找,分配一个长度为x的空间,若找到输出区间的首地址,否则输出Reject New: Free x:释放 ...

  3. fhq_treap || BZOJ 3223: Tyvj 1729 文艺平衡树 || Luogu P3391 【模板】文艺平衡树(Splay)...

    题面: [模板]文艺平衡树(Splay) 题解:无 代码: 1 #include<cstdio> 2 #include<cstring> 3 #include<iostr ...

  4. 伸展树(Splay)

    伸展树(Splay) Splay 是一种二叉查找树,它通过不断将某个节点旋转到根节点,使得整棵树仍然满足二叉查找树的性质,并且保持平衡而不至于退化为链.它由 Daniel Sleator 和 Robe ...

  5. J0ker的CISSP之路:复习-Access Control(4)

    本文同时发表在:[url]http://netsecurity.51cto.com/art/200801/63945.htm[/url] 在<J0ker的CISSP之路>的上一篇文章里,J ...

  6. MFC绘图工具High-speed Charting Control(VS2019)

    MFC绘图工具High-speed Charting Control(VS2019) 前言 一.High-speed Charting Control 1.1 下载 1.2 添加到项目中 二.绘图测试 ...

  7. P1344 [USACO4.4] 追查坏牛奶 Pollutant Control (网络流)

    P1344 [USACO4.4] 追查坏牛奶 Pollutant Control (网络流) 题目链接 文章目录 P1344 [USACO4.4] 追查坏牛奶 Pollutant Control (网 ...

  8. 学习使用Bing Maps Silverlight Control(五):离线使用和自定义地图模式

    6 离线使用 在笔记第一部分的时候就提到如果要使用Bing Maps Silverlight Control 进行开发,需要申请一个key,不让会显示一个错误提示出来.但是在实际开发或使用过程中,使用 ...

  9. BZOJ 1503 郁闷的出纳员(splay)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1503 题意:给出一个数列(初始为空),给出一个最小值Min,当数列中的数字小于Min时自动 ...

最新文章

  1. 如果往错误的NEO地址转账会发生什么
  2. [目录]Pentaho Kettle解决方案:使用PDI构建开源ETL解决方案
  3. WINCE cvrtbin命令简介
  4. oracle or索引失效_oracle数据库中索引会失效的几种情况
  5. MyBatis在Oracle中插入数据并返回主键的问题解决
  6. 测试http请求的Chrome插件:Postman插件的查找安装模拟测试 - 讲解篇
  7. 05 - @property 后面所加的关键词
  8. 如何快速构建一个 Spring Boot 工程?
  9. iOS开发之UITableViewController指定刷新cell 或section
  10. 阶段3 2.Spring_07.银行转账案例_3 分析事务的问题并编写ConnectionUtils
  11. C# Excel 读写数据
  12. 虚幻4引擎虚拟现实项目制作教程
  13. JDK1.8优雅的集合排序(集合的排序)
  14. 运放放大倍数计算公式_运算放大器基本电路大全(转)
  15. jCarouselLite——传送带(多图)
  16. HTML+PHP+MYSQL将数据库中的数据用表格显示
  17. 鞍部在哪里_富春江,富春江在哪里_富春江在哪个省_属于哪个省_就去旅游网
  18. centos7下zeppelin安装配置
  19. mac文件反选_【PS反选键是什么?】Photoshop该如何进行反向选择?
  20. 决策树(二)——决策树的生成

热门文章

  1. Keil 5安装激活教程
  2. 【Android】 Android中适配器简介
  3. python django windows_Python和Django在Windows上的环境搭建
  4. 51nod 2020 排序相减(暴力解法)
  5. 51nod 1414 冰雕 思路:暴力模拟题
  6. 数据结构-----AVL树的插入删除操作
  7. 编写java实用工具-针对未压缩的pdf转word,(java实现),压缩过的pdf勿进
  8. Pixhawk代码分析-姿态解算篇B
  9. GCC如何编译内嵌汇编代码
  10. zzuli 2525: 咕咕的搜索序列