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

    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

    先离散化虚拟内存页,然后用堆来维护最小查询次数,又因为次数相同时还要比较时间,所以我们把次数乘以(m+1)再加上时间,就可以了

      1 const
      2     maxn=10010;
      3     maxm=1000010;
      4 var
      5     n,m,tot,time,ans:longint;
      6     q:array[0..maxn]of longint;
      7     a,b,c,h:array[0..maxm]of longint;
      8     flag:array[0..maxm]of int64;
      9  
     10 procedure swap(var x,y:longint);
     11 var
     12     t:longint;
     13 begin
     14     t:=x;x:=y;y:=t;
     15 end;
     16  
     17 procedure sort(l,r:longint);
     18 var
     19     i,j,z:longint;
     20 begin
     21     i:=l;
     22     j:=r;
     23     z:=a[(l+r)>>1];
     24     repeat
     25       while a[i]<z do
     26         inc(i);
     27       while a[j]>z do
     28         dec(j);
     29       if i<=j then
     30       begin
     31         swap(a[i],a[j]);
     32         swap(b[i],b[j]);
     33         inc(i);
     34         dec(j);
     35       end;
     36     until i>j;
     37     if i<r then sort(i,r);
     38     if j>l then sort(l,j);
     39 end;
     40  
     41 procedure init;
     42 var
     43     i:longint;
     44 begin
     45     read(n,m);
     46     for i:=1 to m do
     47       begin
     48         read(a[i]);
     49         b[i]:=i;
     50       end;
     51     sort(1,m);
     52     for i:=1 to m do
     53       if a[i]<>a[i-1] then c[b[i]]:=i
     54       else c[b[i]]:=c[b[i-1]];
     55 end;
     56  
     57 procedure down(x:longint);
     58 var
     59     i:longint;
     60 begin
     61     i:=x<<1;
     62     while i<=tot do
     63       begin
     64         if (flag[q[i+1]]<flag[q[i]])and(i<tot) then inc(i);
     65         if flag[q[x]]>flag[q[i]] then
     66         begin
     67           swap(q[i],q[x]);
     68           h[q[i]]:=i;
     69           h[q[x]]:=x;
     70           x:=i;
     71           i:=x<<1;
     72         end
     73         else break;
     74       end;
     75 end;
     76  
     77 procedure up(x:longint);
     78 var
     79     i:longint;
     80 begin
     81     while x>1 do
     82       begin
     83         i:=x>>1;
     84         if flag[q[i]]>flag[q[x]] then
     85         begin
     86           swap(q[i],q[x]);
     87           h[q[i]]:=i;
     88           h[q[x]]:=x;
     89           x:=i;
     90         end
     91         else break;
     92       end;
     93 end;
     94  
     95 procedure insert(x:longint);
     96 begin
     97     inc(tot);
     98     h[x]:=tot;
     99     q[tot]:=x;
    100     flag[x]:=time+m+1;
    101     up(tot);
    102 end;
    103  
    104 procedure delete;
    105 begin
    106     flag[q[1]]:=0;
    107     swap(q[1],q[tot]);
    108     h[q[1]]:=1;
    109     h[q[tot]]:=0;
    110     dec(tot);
    111     down(1);
    112 end;
    113  
    114 procedure work;
    115 var
    116     i,j:longint;
    117 begin
    118     for i:=1 to m do
    119       begin
    120         inc(time);
    121         {for j:=1 to m do
    122           write(flag[j],' ');
    123         writeln;
    124         for j:=1 to m do
    125           write(h[j],' ');
    126           writeln;}
    127         if flag[c[i]]<>0 then
    128         begin
    129           inc(ans);
    130           inc(flag[c[i]],m+1);
    131           down(h[c[i]]);
    132         end
    133         else
    134           if tot<n then insert(c[i])
    135           else
    136             begin
    137               delete;
    138               insert(c[i]);
    139             end;
    140       end;
    141     write(ans);
    142 end;
    143  
    144 begin
    145     init;
    146     work;
    147 end.
    View Code
  • 相关阅读:
    软件工程——第一章 软件和软件工程的基本概念
    软件工程——第三章 软件需求分析
    软件工程——第六章 软件测试
    软件工程——第四章 面向过程的软件设计方法
    Statement和PreparedStatement之间的区别(转)
    Eclipse环境变量配置、插件安装、常见错误
    Flex动态读取XML文件并显示在DataGrid中
    修改图层的symbol(AE+C#)
    如何用Httpservice和Webservice来和Flex进行通讯(转)
    flex事件讲解(转)
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3613434.html
Copyright © 2011-2022 走看看