BZOJ-1206 虚拟内存 Hash+离散化+Priority_Queue

时间:2022-08-28 11:40:23
闻说HNOI每年都有一道Hash。

1206: [HNOI2005]虚拟内存

Time Limit: 50 Sec Memory Limit: 162 MB

Submit: 330 Solved: 202

[Submit][Status][Discuss]

Description

操作系统中一种重要的存储管理技术就是虚拟内存技术。操作系统中允许进程同时运行,也就是并行。每个进程都有其相对独立的数据块(进程运行的过程中将对其进行读写操作)。理想的情况下,这些数据块都应该存放在内存中,这样才能实现高效的读写操作。但事实上,内存的容量有限,每个进程只能把一部分数据放在内存中,为了解决这个矛盾,提出了虚拟内存技术。虚拟内存技术的基本原理是:对进程而言,内存空间是无限大的,进程可以随意地读写数据,而对操作系统内部而言,利用外存来模拟扩充的内存空间,进程要求访问某个内存单元时,交由操作系统处理,操作系统首先在内存中查找该单元是否存在,如果存在,查找成功,否则转入外存查找(一定存在于外存中)。就存储介质的物理性质而言,内存的访问速度相对于外存要快得多,因此对于每个进程来说操作系统应该把那些访问次数较多的数据存放在内存中,而把那些访问次数很少的数据放在外存中。如何选择内存中暂留的数据是一个很值得研究的问题,下面介绍一个内存管理中比较常用的算法:内存中的数据以页为基本存储单位,进程的读写操作都针对页来进行。实际内存空间被分割成n页,虚拟内存空间的页数往往要多得多。某一时刻,进程需要访问虚存编号为P的页,该算法的执行步骤如下: a. 首先在内存中查找,如果该页位于内存中,查找成功,转d,否则继续下面的操作; b. 寻找内存中是否存在空页(即没有装载任何数据页的页面),若有,则从外存中读入要查找页,并将该页送至内存中的空页进行存储,然后转d,否则继续下面的操作; c. 在内存中寻找一个访问次数最少的页面(如果存在多个页面的访问次数同时为最少,则选取最早读入数据进入内存的那个页面),从外存中读入要查找页,替换该页。 d. 结束所谓访问次数是指从当前页面进入内存到该时刻被访问的次数,如果该页面以前进入过内存并被其它页面替换,那么前面的访问次数不应计入这个时刻的访问次数中。你的任务是设计一个程序实现上述算法。测试数据将会提供m条读写内存的命令,每条命题提供要求访问的虚拟内存页的编号P。你的程序要求能够模拟整个m条命令的全部执行过程,所有的命令是按照输入的先后执行的,最开始的时候内存中的n页全为空。

Input

第1行为n<10000和m<1000000,分别表示内存页数和读写内存命令条数。接下来有m行,其中第i+1行有一个正整数Pi<=10^9,表示第i条读写内存命令需要访问的虚拟内存页的编号。

Output

仅包含一个正整数,表示在整个模拟过程中,在内存中直接查找成功的次数(即上面的算法只执行步骤a的次数)。

Sample Input

3 8

1

1

2

3

4

2

5

4

Sample Output

1

HINT

Source

hash

这道题目,算是模拟吧,调的时候有一个点忘了,WA了两次,无果后,遂寻男神xym,他竟然用map!!!不过还是看出来了问题,也不算坑。

数据是10^9级的,但实际数量10^6级,所以想到离散;用堆维护,记录三个值:离散后的数值,访问次数,插入堆的顺序;当堆中多于n后,进行替换;值得一提的是要重载运算符(开始自己重载的有点丑,于是借鉴了男神的讨论打了个opreator)

有趣的是,在我调试的时候,电脑弹出了一个提示:

BZOJ-1206   虚拟内存     Hash+离散化+Priority_Queue

真机智QAQ

下面是代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int nc[1000010];
int n,m;
int p[1000010],pi[1000010];
int num=0;int cnt;
int ans=0;
struct data{
int dat,tim,sx;//dat是表示值,tim表示访问次数,sx表示先后顺序
bool operator > (const data &other) const
{
if (tim<other.tim) return 0;
if (tim>other.tim) return 1;
return sx>other.sx;
}
};
priority_queue <data,vector<data>,greater<data> > q; //再开一个数组,专门存放在hash表里的位置 int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
return x*f;
} //查找内存,查找成功,结束,答案+1
//查找失败,查找空页,有空页,插入空页中 结束
//无空页,删除访问数最小的页,插入此页 结束 bool cmp(int a,int b)
{
return a<b;
}
int erfen(int x)
{
int left=1,right=cnt;
while (left<=right)
{
int mid=(left+right)>>1;
if (p[mid]==x) return mid;
if (p[mid]>x) right=mid-1;
else left=mid+1;
}
}
void lsh()
{
sort(p+1,p+m+1,cmp);
cnt=1;
for (int i=2; i<=m; i++)
if (p[i]!=p[i-1]) p[++cnt]=p[i];
for (int i=1; i<=m; i++)
pi[i]=erfen(pi[i]);
} int main()
{
n=read();m=read();
for (int i=1; i<=m; i++)
{p[i]=read();pi[i]=p[i];}
lsh();
for (int i=1; i<=m; i++)
{
int now=pi[i];
int tmp;
nc[now]++;
if (nc[now]>1) {ans++;continue;}//command a.
data x;
x.dat=now,x.tim=1,x.sx=i;
if (q.size()<n) {q.push(x);continue;}//command b.
data y;
y=q.top();
while (y.tim!=nc[y.dat])
{
q.pop();
y.tim=nc[y.dat];
q.push(y);
y=q.top();
}
nc[y.dat]=0;
q.pop();q.push(x);//command c.
}
printf("%d\n",ans);
return 0;
}

BZOJ-1206 虚拟内存 Hash+离散化+Priority_Queue的更多相关文章

  1. BZOJ 1206 &lbrack;HNOI2005&rsqb;虚拟内存:模拟

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1206 题意: 内存大小为n(外存无限大),共有m次访问,每一次访问的信息编号为p. 对于每 ...

  2. 【BZOJ 3098】 Hash Killer II

    Description 这天天气不错,hzhwcmhf神犇给VFleaKing出了一道题:给你一个长度为N的字符串S,求有多少个不同的长度为L的子串.子串的定义是S[l].S[l + 1].... S ...

  3. BZOJ 1818 内部白点&lpar;离散化&plus;树状数组&rpar;

    此题就是1227 的弱化版. 画个图或者稍微证明一下就能够知道,一定不会超过一次变换. 那么我们只需要统计有多少个白点会变黑,换句话说就是有多少个白点上下左右都有黑点. 离散化横坐标,因为没有黑点在的 ...

  4. BZOJ 1227 虔诚的墓主人&lpar;离散化&plus;树状数组&rpar;

    题目中矩形的尺寸太大,导致墓地的数目太多,如果我们统计每一个墓地的虔诚度,超时是一定的. 而常青树的数目<=1e5.这启发我们从树的方向去思考. 考虑一行没有树的情况,显然这一行的墓地的虔诚度之 ...

  5. &lbrack;Sdoi2013&rsqb; &lbrack;bzoj 3198&rsqb; spring &lpar;hash&plus;容斥原理&rpar;

    题目描述 给出nnn个666维坐标,求有多少对点对满足恰好mmm个位置相等 1<=n<=1051<=n<=10^51<=n<=105 0<=k<=60& ...

  6. bzoj 1067&colon; &lbrack;SCOI2007&rsqb;降雨量 &lpar;离散化&plus;线段树&rpar;

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1067 思路: 毒瘤题,写的自闭,改了一晚上,注意要理清题目的逻辑 x小于等于y,x,y之间的 ...

  7. BZOJ 2084 二分&plus;hash OR Manacher

    思路: 二分+哈希 //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> ...

  8. BZOJ 3357&colon; &lbrack;Usaco2004&rsqb;等差数列

    3357: [Usaco2004]等差数列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 338  Solved: 160[Submit][Statu ...

  9. 南阳理工 题目9&colon;posters(离散化&plus;线段树)

    posters 时间限制:1000 ms  |  内存限制:65535 KB 难度:6   描述 The citizens of Bytetown, AB, could not stand that ...

随机推荐

  1. 从I&sol;O复用谈epoll为什么高效

    上一篇文章中,谈了一些网络编程的基本概念.在现实使用中,用的最多的就是I/O复用了,无非就是select,poll,epoll 很多人提到网络就说epoll,认为epoll效率是最高的.单纯的这么认为 ...

  2. IOS开发基础知识--碎片3

    十二:判断设备 //设备名称 return [UIDevice currentDevice].name; //设备型号,只可得到是何设备,无法得到是第几代设备 return [UIDevice cur ...

  3. Effective Objective-C 2&period;0 — 第四条:多用类型常量,少用&num;define预处理指令

    第四条:多用类型常量,少用#define预处理指令 使用#define 预处理的坏处:定义出来的常量没有类型信息,编译器只是会在编译前据此执行查找与替换操作.即使有人重新定义了常量值,编译器也不会产生 ...

  4. Python--关于set

    慕课网<Pyrhon入门>学习笔记 1.set 特性 set 持有一系列元素,这一点和 list 很像,但是set的元素没有重复,而且是无序的,这点和 dict 的 key很像. 可以将s ...

  5. &period;net视图中日期格式化

    昨天在做一个功能,要在界面上按照规定的格式显示一个时间,如果直接在expression那里格式化的话(如下:) @Html.DisplayFor(c => Convert.ToDateTime( ...

  6. C语言关键字 - 铁布衫:const 转载

    const 描述:相传C世界中出现了一件*装备const,它能的出现,让天下所有的刺客,黑客都失业了,在它的保护下,所有的变量都可以完好无损. 作用:const是constant的简写,表示海枯石栏 ...

  7. Linux2&period;6内核--内存管理(1)--分页机制

          在内核里分配内存可不像在其他地方分配内存那么容易.造成这种局面的因素很多.从根本上讲,是因为内核本身不能像用户空间那样奢侈的使用内存.内核与用户空间不同,它不具备这种能力,它不支持简单便捷 ...

  8. 理解、学习与使用 Java 中的 Optional

    从 Java 8 引入的一个很有趣的特性是 Optional  类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) -- 每个 Java 程序员都 ...

  9. spark on yarn 内存分配

    Spark On YARN内存分配 本文主要了解Spark On YARN部署模式下的内存分配情况,因为没有深入研究Spark的源代码,所以只能根据日志去看相关的源代码,从而了解“为什么会这样,为什么 ...

  10. php根据时间显示刚刚&comma;几分钟前&comma;几小时前的实现代码

    发布时间距现在的时间 function tranTime($time) { $rtime = date("m-d H:i", $time); $htime = date(&quot ...