4272: 最佳淘汰算法
Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 396 Solved: 58
Description
提出最佳页面淘汰算法。是操作系统存储管理中的一种全局页面替换策略当要调入一页而必须淘汰旧页时,应该淘汰以后不再访问的页,或距现在最长时间后要访问的页面。它所产生的缺页数最少,然而,却需要预测程序的页面引用串,这是无法预知的,不可能对程序的运行过程做出精确的断言。但是我们在这里会告诉你一个已经存在的一个页面序列,请输出最终在内存中存在的页面即可。
Input
有多组数据(组数<=21)。
每组数据输入形如:
n m
a1 a2 a3 a4 .... an
其中n(n,m<=500000)表示已知页面序列的长度。
ai(0<=ai<=100000)表示页面类型,为整数。
m为在内存中保存的页面类型数量。
Output
输出形如:
b1 b2 b3 .... bk
具体要求请仔细阅读样例和Hint。
Sample Input
21 37 0 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 13 22 1 34 31 0 0 1
Sample Output
7 0 13 11 0
解题思路:
用优先队列去维护距离下一个同类型页面最远的编号,再用一个大小为m的数组去存页面内容就好了。当m数组没有填满的时候,就直接填进去就好了,当m数组填满了后,我们就根据情况替代里面的元素。但是需要注意一个trick,出现一个数组里已经存在的编号的的页面的时候,不可以直接continue,虽然不能进入内存,但需要更新下这个编号下一次出现的位置,如果不更新就会出错,直接塞进优先队列里就好了。
另外这个题还加深了我对优先队列的认识,因为踩了个大坑,我之前是用这种代码去写的优先队列的<重载函数:
bool operator <(const p &a)const
{
if(ww[a.x]!=ww[x])return ww[a.x]>x;
else return a.x>x;
}
然后果断gg,我生成了一些数据,发现中间有些地方,队列里第一个元素的ww值反而小于第二个元素的ww值,非常奇怪。后来才发现,是因为我在中间过程中修改过ww数组的值,而由于这时候可能没有重新插入元素,所以优先队列没有调整,所以直到下一次修改优先队列之前优先队列肯定就是不优先的了,所以会发生错误。
所以说,以后写代码不要写这种奇奇怪怪的风格的代码,容易踩到莫名的坑。这里要注意的就是
优先队列千万别用外部元素来写重载函数
优先队列千万别用外部元素来写重载函数
优先队列千万别用外部元素来写重载函数
代码:
#include <bits/stdc++.h>
#define ps push_back
using namespace std;
const int maxn=5e5+5;
const int inf=5e5+5;
int n, m;
int h[500000+6];
int pos[500000+5];
struct p
{
int w;
int y;
int x;
bool operator <(const p &a)const
{
if(a.w!=w)return a.w>w;
else return a.x>x;
}
};
int b[maxn];
int ans[maxn];
int book[500000+5];
int po[maxn];
int num[500000+5];
bool cmp(p a, p b)
{
return a.y<b.y;
}
int main()
{
// freopen("C:\\Users\\johsnow\\Desktop\\in.txt", "r", stdin);
// freopen("C:\\Users\\johsnow\\Desktop\\out2.txt", "w", stdout);
int i, j;
p node;
// scanf("%d%d", &n, &m);
while(~scanf("%d%d", &n, &m))
{
memset(book, 0, sizeof book);
memset(ans, 0, sizeof ans);
priority_queue <p>a;
int ma=0;
for(i=0; i<n; i++)
{
scanf("%d", &b[i]);
ma=b[i]>ma?b[i]:ma;
}
for(i=0; i<=ma; i++)pos[i]=inf;
for(i=n-1; i>=0; i--)
{
h[i]=pos[b[i]];
pos[b[i]]=i;
}
int top=1, tmp;
for(i=0; i<n; i++)
{
node.x=b[i];
node.y=i;
node.w=h[i];
if(top<=m)
{
if(book[b[i]]==0)
{
// printf("%d\n", b[i]);
ans[top]=b[i];
book[b[i]]=top;
// printf("%d %d\n", b[i], book[b[i]]);
top++;
}
a.push(node);
}
else break;
}
j=i;
if(top<=m)
{
for(i=1; i<top; i++)printf(i==top-1?"%d\n":"%d ", ans[i]);
continue;
}
for(i=j; i<n; i++)
{
node.x=b[i];
node.w=h[i];
if(book[b[i]]==0)
{
tmp=book[a.top().x];
book[a.top().x]=0;
ans[tmp]=b[i];
// printf("%d %d\n", b[i], tmp);
book[b[i]]=tmp;
a.pop();
}
a.push(node);
}
for(i=1; i<top; i++)printf(i==top-1?"%d\n":"%d ", ans[i]);
}
}