1 条题解
-
3
内存的规则符合优先队列的特点,可以用一个优先队列,内部元素A包含tag idx cnt三个变量,分别表示时间戳(用于判断谁先进入内存)、页编号、访问次数。由于编号范围比较大,因此需要离散化。队列元素的优先级是:访问次数越少,优先级越高。访问次数相同时,时间戳越小,优先级越高。
使用数组c记录每个页被访问的次数,如果当前页的c值大于0,说明成功命中。否则,如果内存还没有满,可以把当前页加入内存,并把页信息加入队列。如果内存已满,需要从优先队列里取出队首,如果队首的cnt和实际的c值不同,说明入队后它的访问次数增加了,此时需要用新的次数重新入队,然后继续取出新的队首,直到其cnt和实际c值相同为止。此时需要把队首出队,然后把新的页入队。
在上述过程中统计命中的次数,即为答案。
参考代码
#include <bits/stdc++.h> using namespace std; const int MAXN = 1e6 + 100; struct A { int tag, idx, cnt; bool operator < (const A& x) const { if (cnt == x.cnt) return tag > x.tag; return cnt > x.cnt; } }; int n, m, p[MAXN], c[MAXN], sz, ans; priority_queue<A> que; vector<int> v; int main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); cin >> n >> m; for (int i = 1; i <= m; i++) { cin >> p[i]; v.push_back(p[i]); } sort(v.begin(), v.end()); v.erase(unique(v.begin(), v.end()), v.end()); for (int i = 1; i <= m; i++) { p[i] = lower_bound(v.begin(), v.end(), p[i]) - v.begin(); if (c[p[i]] > 0) { c[p[i]]++; ans++; } else if (sz < n) { c[p[i]] = 1; que.push({i, p[i], 1}); sz++; } else { while (que.top().cnt != c[que.top().idx]) { A tp = que.top(); que.pop(); que.push({tp.tag, tp.idx, c[tp.idx]}); } c[que.top().idx] = 0; que.pop(); c[p[i]] = 1; que.push({i, p[i], 1}); } } cout << ans; return 0; }
- 1
信息
- ID
- 713
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 2
- 标签
- (无)
- 递交数
- 30
- 已通过
- 22
- 上传者