zoukankan      html  css  js  c++  java
  • BZOJ1206:[HNOI2005]虚拟内存

    Description

    操作系统中一种重要的存储管理技术就是虚拟内存技术。操作系统中允许进程同时运行,也就是并行。每个进程都有其相对独立的数据块(进程运行的过程中将对其进行读写操作)。理想的情况下,这些数据块都应该存放在内存中,这样才能实现高效的读写操作。但事实上,内存的容量有限,每个进程只能把一部分数据放在内存中,为了解决这个矛盾,提出了虚拟内存技术。虚拟内存技术的基本原理是:对进程而言,内存空间是无限大的,进程可以随意地读写数据,而对操作系统内部而言,利用外存来模拟扩充的内存空间,进程要求访问某个内存单元时,交由操作系统处理,操作系统首先在内存中查找该单元是否存在,如果存在,查找成功,否则转入外存查找(一定存在于外存中)。就存储介质的物理性质而言,内存的访问速度相对于外存要快得多,因此对于每个进程来说操作系统应该把那些访问次数较多的数据存放在内存中,而把那些访问次数很少的数据放在外存中。如何选择内存中暂留的数据是一个很值得研究的问题,下面介绍一个内存管理中比较常用的算法:内存中的数据以页为基本存储单位,进程的读写操作都针对页来进行。实际内存空间被分割成n页,虚拟内存空间的页数往往要多得多。

    某一时刻,进程需要访问虚存编号为P的页,该算法的执行步骤如下:

    a. 首先在内存中查找,如果该页位于内存中,查找成功,转d,否则继续下面的操作;

    b. 寻找内存中是否存在空页(即没有装载任何数据页的页面),若有,则从外存中读入要查找页,并将该页送至内存中的空页进行存储,然后转d,否则继续下面的操作;

    c. 在内存中寻找一个访问次数最少的页面(如果存在多个页面的访问次数同时为最少,则选取最早读入数据进入内存的那个页面),从外存中读入要查找页,替换该页。

    d. 结束

    所谓访问次数是指从当前页面进入内存到该时刻被访问的次数,如果该页面以前进入过内存并被其它页面替换,那么前面的访问次数不应计入这个时刻的访问次数中。你的任务是设计一个程序实现上述算法。测试数据将会提供m条读写内存的命令,每条命题提供要求访问的虚拟内存页的编号P。你的程序要求能够模拟整个m条命令的全部执行过程,所有的命令是按照输入的先后执行的,最开始的时候内存中的n页全为空。

    Input

    第1行为n和m,分别表示内存页数和读写内存命令条数。接下来有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

    n<10000,m<1000000

    题解:

    题面巨长无比,就是要让你按照给出的规则去维护一个堆,支持插入、删除、修改等操作。

    stl练习题,操作可以用set与map解决。

    代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 struct yuansu
     4 {
     5   int a,b,c;
     6   bool operator<(const yuansu &thr)const{return (a<thr.a)or((a==thr.a)and(b<thr.b));};
     7 };
     8 struct yuansu2
     9 {
    10   int a,b,c;
    11 };
    12 map<int,yuansu2> hash;
    13 multiset<yuansu> dui;
    14 int tot,ans,n,m;
    15 int main()
    16 {
    17   scanf("%d%d",&n,&m);
    18   for(int i=1;i<=m;i++)
    19   {
    20       int a; scanf("%d",&a);
    21       if(hash[a].c==1)
    22       {
    23         ans++;
    24         multiset<yuansu>::iterator t=dui.find((yuansu){hash[a].a,hash[a].b,a});
    25         yuansu e=(*t); dui.erase(t); hash[a].a++; e.a++; dui.insert(e);
    26     }
    27       else if(tot==n)
    28       {
    29         yuansu e=(*dui.begin()); dui.erase(dui.begin()); hash[e.c].c=0;
    30         dui.insert((yuansu){1,i,a}); hash[a].c=1; hash[a].a=1; hash[a].b=i;
    31       }
    32       else
    33     { 
    34         dui.insert((yuansu){1,i,a}); hash[a].c=1; hash[a].a=1; hash[a].b=i; tot++;
    35       }
    36   }
    37   printf("%d
    ",ans);
    38 }
    View Code
  • 相关阅读:
    Class.getSimpleName()的作用
    win7下制作ubuntu系统安装启动盘和U盘安装ubuntu全过程
    奈奎斯特三大准则
    [转]OFDM中保护间隔和循环前缀抵抗ISI和ICI
    频偏
    移动通信里面,OFDM技术所说的“载波相互正交”是什么意思?
    虚拟盘符映射
    npm 安装与常用命令
    ASP.NET WebAPI HTTPS
    记录下自己写的gulp打包脚本
  • 原文地址:https://www.cnblogs.com/GhostReach/p/6402094.html
Copyright © 2011-2022 走看看