问题描述

在计算机中,CPU只能和高速缓存Cache直接交换数据。当所需的内存单元不在Cache中时,则需要从主存里把数据调入Cache。此时,如果Cache容量已满,则必须先从中删除一个。 例如,当前Cache容量为3,且已经有编号为10和20的主存单元。 此时,CPU访问编号为10的主存单元,Cache命中。 接着,CPU访问编号为21的主存单元,那么只需将该主存单元移入Cache中,造成一次缺失(Cache Miss)。 接着,CPU访问编号为31的主存单元,则必须从Cache中换出一块,才能将编号为31的主存单元移入Cache,假设我们移出了编号为10的主存单元。 接着,CPU再次访问编号为10的主存单元,则又引起了一次缺失。我们看到,如果在上一次删除时,删除其他的单元,则可以避免本次访问的缺失。 在现代计算机中,往往采用LRU(最近最少使用)的算法来进行Cache调度——可是,从上一个例子就能看出,这并不是最优的算法。 对于一个固定容量的空Cache和连续的若干主存访问请求,聪聪想知道如何在每次Cache缺失时换出正确的主存单元,以达到最少的Cache缺失次数。

输入格式

输入文件第一行包含两个整数N和M(1<=M<=N<=100,000),分别代表了主存访问的次数和Cache的容量。 第二行包含了N个空格分开的正整数,按访问请求先后顺序给出了每个主存块的编号(不超过1,000,000,000)。

输出格式

输出一行,为Cache缺失次数的最小值。

样例输入

6 2

1 2 3 1 2 3

样例输出

4

样例解释

在第4次缺失时将3号单元换出Cache。

解析

感性理解一下,每次换出下一次出现最远的是最优的。那么我们用优先队列维护Cache中的主存单元,排序关键字为下一次出现的位置,如果目前插入的元素已经在队列中了,就直接插入队列,否则若Cache已满就弹出队首元素再插入,若没满就直接插入。具体还可以用set辅助实现。

代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <set>
#include <queue>
#define N 100002
using namespace std;
struct task{
int id,p,nxt;
bool operator < (const task &x) const{
return x.nxt>nxt;
}
}a[N];
int n,m,i,c,ans;
priority_queue<task> q;
set<int> s;
int cmp1(const task &x,const task &y)
{
if(x.id==y.id) return x.p<y.p;
return x.id<y.id;
}
int cmp2(const task &x,const task &y)
{
return x.p<y.p;
}
int main()
{
cin>>n>>m;
for(i=1;i<=n;i++){
cin>>a[i].id;
a[i].p=i;
}
sort(a+1,a+n+1,cmp1);
for(i=2;i<=n+1;i++){
if(a[i].id==a[i-1].id) a[i-1].nxt=a[i].p;
else a[i-1].nxt=1<<30;
}
sort(a+1,a+n+1,cmp2);
for(i=1;i<=n;i++){
int x=a[i].id;
if(s.count(x)){
q.push(a[i]);
continue;
}
ans++;
if(s.size()==m) s.erase(q.top().id),q.pop();
s.insert(x);
q.push(a[i]);
}
cout<<ans<<endl;
return 0;
}

[BZOJ1826] 缓存交换的更多相关文章

  1. 【BZOJ1826】[JSOI2010]缓存交换(贪心)

    [BZOJ1826][JSOI2010]缓存交换(贪心) 题面 BZOJ 洛谷 题解 当缓存不满显然直接放进去,满了之后考虑拿走哪一个.不难发现拿走下一次出现时间最晚的那个一定不会更差. 那么用一个堆 ...

  2. bzoj1528[POI2005]sam-Toy Cars*&&bzoj1826[JSOI2010]缓存交换

    bzoj1528[POI2005]sam-Toy Cars bzoj1826[JSOI2010]缓存交换 题意: Jasio有n个不同的玩具,它们都被放在了很高的架子上,地板上不会有超过k个玩具.当J ...

  3. BZOJ_1826_[JSOI2010]缓存交换 _线段树+贪心

    BZOJ_1826_[JSOI2010]缓存交换 _线段树+贪心 Description 在计算机中,CPU只能和高速缓存Cache直接交换数据.当所需的内存单元不在Cache中时,则需要从主存里把数 ...

  4. 1826: [JSOI2010]缓存交换

    1826: [JSOI2010]缓存交换 https://www.lydsy.com/JudgeOnline/problem.php?id=1826 分析: 简单的贪心,然后调啊调...最近怎么了,码 ...

  5. 无缓存交换 牛客网 程序员面试金典 C++ Python

    无缓存交换 牛客网 程序员面试金典 C++ Python 题目描述 请编写一个函数,函数内不使用任何临时变量,直接交换两个数的值. 给定一个int数组AB,其第零个元素和第一个元素为待交换的值,请返回 ...

  6. BZOJ1826 [JSOI2010]缓存交换 堆 贪心

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1826 题意概括 Cache中有m个储存单元,接下来有n个访问地址,每个地址用一个数字表示.访问每一 ...

  7. [bzoj1826] [JSOI2010]缓存交换

    虽然不知道为什么..但显然,每次扔掉离下次查询最远的内存单元就行了233 用堆来维护贪心...(优先队列大法好 #include<cstdio> #include<iostream& ...

  8. Luogu P4404 [JSOI2010]缓存交换 优先队列

    细节题?...调了半天.... 可以发现,每一次从缓存中删除的主存一定是下次访问最晚的,可以用优先队列来处理...还有要离散化...还有链表末尾要多建一些点...否则会死的很惨... #include ...

  9. B1826 [JSOI2010]缓存交换 贪心+离散化+堆

    这个题仔细一想可以直接贪心做,因为队列里下一个出现的早的一定最优.正确性显然.然后我只拿了50,我直接模拟另一个队列暴力修改最后一个点的nxt值,自然会T.但是其实不用修改,直接插入就行了前面的不影响 ...

随机推荐

  1. curl_init raw传递json参数

    protected function curl_vm_record($url, $platform, $authorization, $jsonStr) { $ch = curl_init(); cu ...

  2. Delphi XE2 之 FireMonkey 入门(14) - 滤镜: 概览

    相关单元: FMX.Filter FMX.FilterCatBlur FMX.FilterCatGeometry FMX.FilterCatTransition FMX_FilterCatColor ...

  3. 监测工具dstat使用说明

    参考地址: https://blog.csdn.net/sinat_34789167/article/details/80986709

  4. base64编解码的两个函数(安全版本)

    void base64_encode_s(const unsigned char *str, long inlen, std::string& outstr, long* lpBufLen) ...

  5. exceptions: django2.2/ mysql ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3

    在centos部署python应用后访问页面,显示如下异常信息 报错环境 python=3.6,django=2.2……django.core.exceptions.ImproperlyConfigu ...

  6. 从SOA 谈软件的发展

    本文是个科普文章,有些内容可能不精准,为了给女儿解释SOA所写.要深刻理解SOA,必须了解软件的发展过程.互联网上有大量的这方面的文章可以参考. 软件与计算机 软件这个概念很年轻,也就不到70年. 软 ...

  7. 数论-欧拉函数-LightOJ - 1370

    我是知道φ(n)=n-1,n为质数  的,然后给的样例在纸上一算,嗯,好像是找往上最近的质数就行了,而且有些合数的欧拉函数值还会比比它小一点的质数的欧拉函数值要小,所以坚定了往上找最近的质数的决心—— ...

  8. Vue.js 注册组件

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. Lucene 4.6.1 java.lang.IllegalStateException: TokenStream contract violation

    这是旧代码在新版本Lucene中出现的异常,异常如下: Exception in thread "main" java.lang.IllegalStateException: To ...

  10. Spark-Core RDD转换算子-Value型

    1. map(func) 作用: 返回一个新的 RDD, 该 RDD 是由原 RDD 的每个元素经过函数转换后的值而组成. 就是对 RDD 中的数据做转换. 创建一个包含1-10的的 RDD,然后将每 ...