https://www.luogu.org/problem/P4404

题意

你有一个大小为n的缓存区,有个长度为m的查询序列。

每次查询的时候需要把查询值放入缓存,若缓存已满,则先删除任一位置再将其放入,若缓存内已有当前值,则无需再次放入

求放入缓存这个操作的最少执行次数

n,m≤1e5

序列中的数<=1,000,000,000

分析

很明显的贪心, 但要想想贪心的策略

其实这题做的很玄(感觉我每次做题都很玄,因为是听完luogu讲师讲完之后做的题目,思路什么的都有提示...

这道题首先要做的就是把前m个不同的数放到缓存里面,然后依次加数,删数...也就是一个模拟。

但怎么删数呢?这里给出的策略是删除缓存中一个数x: 在缓存外,x对应的第一个与它相等的数y 的位置最靠后。

原因:(我只知道这样做是对的,但不知道怎么想到的...毕竟我只画了几个例子,思路老师说的)

这样子做,可以使删除操作对放入缓存次数的影响最小,即 使放入缓存的操作数增加的最小,如果我们不这做,那么 y 之前必定有数z,经历了先删除又放入,而先删x的话,至少不会使放入缓存的操作更多....吧(我其实也不是hin懂,看看实现就行了

实现:预处理一下y(即代码中的next),用堆存这个玩意,注意离散化,注意模拟的过程就好了

实现

#include<cstdio>
#include<algorithm>
#include<string.h>
#include<queue>
using namespace std;
#define MAX 100000+9 int n,m,ans, tag = 1;
struct node{
int a,n,k;
}a[MAX];
bool cmp1(node x, node xxx) { return x.a < xxx.a;}
bool cmp2(node x, node xxx) { return x.n < xxx.n;} int last[MAX], next[MAX], vis[MAX];
struct node2{
int num, next;
bool operator < (const node2& xxx) const {
return next < xxx.next ;
}
}; priority_queue<node2> q; int main() {
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; i++) scanf("%d",&a[i].a ), a[i].n = i;
sort(a+1, a+1+n, cmp1);
int tot = 0;
for(int i = 1; i <= n; i++) {
a[i].k = ++tot;
while(a[i+1].a == a[i].a ) a[++i].k = tot;
}
sort(a+1, a+1+n, cmp2);
// for(int i = 1; i <= n; i++) printf("%d ",a[i].k );
// printf("\n");
//注意,若满的缓存区里有一元素x,并且查询序列中没有了x,那么x一定是要先删的,所以设为INF
memset(last , 0x3f , sizeof(last));
for(int i = n; i >= 1; i--) {
next[i] = last[a[i].k ];
last[a[i].k ] = i;
}
// for(int i = 1; i <= n; i++) printf("%d ",next[i] );
// printf("\n");
for(int i = 1; i <= n; i++) {
if(ans == m) {
tag = 2;
}
if(tag == 1 && vis[a[i].k] == 0) {//没放满m ,且a[i].k不在队中
ans++;
vis[a[i].k ] = 1;
}
if(tag == 2 && vis[a[i].k] == 0) {//放满的m,且a[i].k不在队中
ans++;
vis[a[i].k ] = 1;
vis[q.top().num] = 0;
q.pop();
}
node2 tmp;
tmp.num = a[i].k , tmp.next = next[i];
q.push(tmp);
}
printf("%d",ans);
return 0;
}
/*
6 2
1 222 3333 1 222 3333
*/

luoguP4404缓存交换的更多相关文章

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

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

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

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

  3. 1826: [JSOI2010]缓存交换

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

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

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

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

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

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

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

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

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

  8. [BZOJ1826] 缓存交换

    问题描述 在计算机中,CPU只能和高速缓存Cache直接交换数据.当所需的内存单元不在Cache中时,则需要从主存里把数据调入Cache.此时,如果Cache容量已满,则必须先从中删除一个. 例如,当 ...

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

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

随机推荐

  1. filebench - File system and storage benchmark - 模拟生成各种各样的应用的负载 - A Model Based File System Workload Generator

    兼容posix 接口的文件系统中我们不仅要测试 posix 接口是否兼容.随机读,随机写,顺序读,顺序写等读写模式下的性能.我们还要测试在不同工作负载条件下的文件系统的性能的情况:Filebench ...

  2. vue预览本地图片

    <template> <div> <a href="javascript:void(0);" @change="addImage" ...

  3. WPF 精修篇 自定义控件

    原文:WPF 精修篇 自定义控件 自定义控件 因为没有办法对界面可视化编辑 所以用来很少 现在实现的是 自定义控件的 自定义属性 和自定义方法 用VS 创建自定义控件后 会自动创建 Themes 文件 ...

  4. awk命令使用整理

    1. awk默认以空格分隔, 可摘出指定位置的内容, 通常用法如下( 文件名称为file.txt ): 文件中行内容为:  12:3   a  4:56   b awk  '{print $1}'  ...

  5. 用arthas的watch方法观察执行方法的输入输出

    watch 的参数比较多,主要是因为它能在 4 个不同的场景观察对象 参数名称 参数说明 class-pattern 类名表达式匹配 method-pattern 方法名表达式匹配 express 观 ...

  6. 解决SQL Server中无管理员账户权限问题

    遇到忘记SQL Server管理员账户密码或管理员账户被意外删除的情况,如何在SQL Server中添加一个新的管理员账户?按一下步骤操作可添加一个windows账户到SQL Server中,并分配数 ...

  7. Codeforces Round #599 (Div. 1) A. Tile Painting 数论

    C. Tile Painting Ujan has been lazy lately, but now has decided to bring his yard to good shape. Fir ...

  8. vscode源码分析【五】事件分发机制

    第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 第三篇:vscode源码分析[三]程序的启动逻辑,性能问题的追踪 ...

  9. springboot整合shiro进行权限管理

    背景:springboot2.1,shiro1.4:由于目前的小项目没做登录,但是客户又需要加上权限,因此楼主就想到了shiro(这是单独的项目,需要集成后台管理系统) shiro简介 Apache ...

  10. kindEditor 修改上传图片的路径

    压缩过的js类似