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
原文地址:https://www.cnblogs.com/Randolph87/p/3613434.html