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. CodeForces - 1230C(思维/暴力)

    题意 https://vjudge.net/problem/CodeForces-1230C 给了你总共有21张多米诺骨牌,每张牌有两个面,然后给你一个无向图,保证没有环和一个顶点多条边的情况存在.现 ...

  2. 实操《kubernetes网络权威指南》之tun设备

    跟着网上作一次,OK的. tun.c #include <net/if.h> #include <sys/ioctl.h> #include <sys/stat.h> ...

  3. jenkins报错:Problem accessing /jenkins/. Reason: HTTP ERROR 404

    这是一个Jenkins的Bug.临时解决方法是:在浏览器中手工输入:http://<ip>:<port>.不要访问"/jenkins"这个路径.

  4. 关于sublime建立python工程的说明

    https://www.zhihu.com/question/22681628此链接说明的不错,可以参考. 为了方便使用sublime,难免要定义一些快捷键,https://www.whidy.net ...

  5. Luogu P5408 【模板】第一类斯特林数·行

    为什么要做这题呢,当然是有用啊qwq 首先我们考虑非常经典的式子: \[x^{\overline{n}}=\sum_i \left[^n_i\right] x^i\] 然后上倍增: \[x^{\ove ...

  6. Mac OSX vim配色方案选择

    首先查看系统自带的vim配色种类: ls /usr/share/vim/vim73/colors 大致输出如下: README.txt default.vim elflord.vim morning. ...

  7. 四种PHP异步执行的常用方式

    本文为大家讲述了php异步调用方法,分享给大家供大家参考,具体内容如下 客户端与服务器端是通过HTTP协议进行连接通讯,客户端发起请求,服务器端接收到请求后执行处理,并返回处理结果. 有时服务器需要执 ...

  8. laravel中视图的基本使用(七)

    laravel中的视图默认保存在 resources\views 目录下.在控制器中,我们通常使用 view() 方法返回一个视图文件. <?php namespace App\Http\Con ...

  9. Spring Cloud中Hystrix 线程隔离导致ThreadLocal数据丢失问题分析

    最近spring boot项目中由于使用了spring cloud 的hystrix 导致了threadLocal中数据丢失,其实具体也没有使用hystrix,但是显示的把他打开了,导致了此问题. 导 ...

  10. 使用maven快速入门

    Maven 基础知识 官网: 传送门 Maven 项目结构 $ MavenProject |-- pom.xml |-- src | |-- main | | `-- java | | `-- res ...