P1177

[HNOI2005]虚拟内存

[HNOI2005]虚拟内存

虚拟内存是操作系统中一种重要的存储管理技术。操作系统允许多个进程同时运行,每个进程都有相对独立的数据块,并会在运行过程中对这些数据进行读写。理想情况下,所有数据都应存放在内存中,以实现高效的读写操作。然而,内存容量有限,每个进程只能将部分数据存放在内存中,因此需要利用虚拟内存技术解决这一矛盾。

对于进程而言,虚拟内存空间可以视为无限大,进程能够任意读写其中的数据;对于操作系统而言,则使用外存模拟扩充出的内存空间。当进程请求访问某个内存单元时,操作系统首先在内存中查找该单元。如果查找成功,就直接进行访问;否则转入外存查找,而该单元一定存在于外存中。

由于内存的访问速度远快于外存,操作系统应尽可能将访问次数较多的数据保留在内存中,将访问次数较少的数据放在外存中。本题采用如下内存管理算法。

内存中的数据以页为基本存储单位,进程的读写操作也以页为单位。实际内存空间被划分为 nn 页,而虚拟内存空间通常包含更多的页。某一时刻,进程需要访问虚拟内存中编号为 PP 的页,算法按照以下步骤执行:

  1. 首先在内存中查找该页。如果该页位于内存中,则查找成功,并结束本次访问;否则继续执行下一步。
  2. 检查内存中是否存在空页,即尚未装载任何数据页的页面。如果存在,则从外存读入待访问的页,并将其存入一个空页中,然后结束本次访问;否则继续执行下一步。
  3. 在内存中选择访问次数最少的页面。如果有多个页面的访问次数同为最少,则选择其中最早被读入内存的页面。从外存读入待访问的页,并替换所选页面。
  4. 结束本次访问。

一个页面的访问次数,是指该页面自本次进入内存以来被访问的次数。如果该页面曾经进入过内存,但后来被其他页面替换,那么此前的访问次数不计入本次进入内存后的访问次数。

现在给出 mm 条按顺序执行的内存读写命令,每条命令指定一个需要访问的虚拟内存页编号 PP。初始时,内存中的 nn 页均为空。请模拟所有命令的执行过程,并统计直接在内存中查找成功的次数。

输入格式

第一行包含两个整数 nn 和 mm,分别表示内存页数和读写内存命令的条数。

接下来 mm 行,第 i+1i+1 行包含一个正整数 PiP_i,表示第 ii 条命令需要访问的虚拟内存页编号。

输出格式

输出一个非负整数,表示整个模拟过程中直接在内存中查找成功的次数。

样例输入

3 8
1
1
2
3
4
2
5
4

样例输出

1

数据范围

  • 1≤n≤1041\le n\le 10^4;
  • m<106m<10^6;
  • PiP_i 为正整数,且 Pi≤109P_i\le 10^9。

来源与许可

本题为 HNOI 2005 试题「虚拟内存」,题面与测试数据整理自 BZOJ。

样例 1

输入

3 8
1
1
2
3
4
2
5
4

输出

1