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

Description

在计算机中,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缺失次数。

Input

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

Output

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

Sample Input

6 2
1 2 3 1 2 3

Sample Output

4

HINT

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


考虑x数某次出现的位置到它下一次出现的位置这段区间。

如果我想要让x不缺失,需要在这段区间里让x进入cache,相当于在这个区间(左开右开)塞一个数。

那么整个序列中,每个位置中最多能塞入m-1个数,因为x这个数已经在cache里了。

然后就变成了另一道题:http://www.cnblogs.com/suika/p/8711400.html

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 200050
#define ls p<<1
#define rs p<<1|1
int n,m;
int t[N<<2],add[N<<2],now[N],tot;
struct A {
int num,id,v;
}a[N];
struct node {
int l,r;
}b[N];
bool cmp1(const A &x,const A &y){return x.num<y.num;}
bool cmp2(const A &x,const A &y){return x.id<y.id;}
bool cmp3(const node &x,const node &y) {
if(x.r==y.r) return x.l>y.l;
return x.r<y.r;
}
void pushdown(int p) {
if(add[p]) {
int d=add[p];
add[ls]+=d; t[ls]+=d;
add[rs]+=d; t[rs]+=d;
add[p]=0;
}
}
void build(int l,int r,int p) {
t[p]=m-1;
if(l==r) {return ;}
int mid=(l+r)>>1;
build(l,mid,ls); build(mid+1,r,rs);
}
int query(int l,int r,int x,int y,int p) {
if(x<=l&&y>=r) return t[p];
int mid=(l+r)>>1,re=1<<30;
pushdown(p);
if(x<=mid) re=min(re,query(l,mid,x,y,ls));
if(y>mid) re=min(re,query(mid+1,r,x,y,rs));
t[p]=min(t[ls],t[rs]);
return re;
}
void update(int l,int r,int x,int y,int v,int p) {
if(x<=l&&y>=r) {
t[p]+=v; add[p]+=v;
return ;
}
pushdown(p);
int mid=(l+r)>>1;
if(x<=mid) update(l,mid,x,y,v,ls);
if(y>mid) update(mid+1,r,x,y,v,rs);
t[p]=min(t[ls],t[rs]);
}
int main() {
memset(t,0x3f,sizeof(t));
scanf("%d%d",&n,&m);
int i;
for(i=1;i<=n;i++) {
scanf("%d",&a[i].num); a[i].id=i;
}
sort(a+1,a+n+1,cmp1);
int j=0;a[0].num=1<<30;
for(i=1;i<=n;i++) {
if(a[i].num!=a[i-1].num)j++;
a[i].v=j;
}
sort(a+1,a+n+1,cmp2);
int ans=n;
for(i=n;i>=1;i--) {
if(now[a[i].v]) {
b[++tot].l=i+1;
b[tot].r=now[a[i].v]-1;
if(b[tot].l>b[tot].r) tot--,ans--;
}
now[a[i].v]=i;
}
sort(b+1,b+tot+1,cmp3);
build(1,n,1);
for(i=1;i<=tot;i++) {
int re=query(1,n,b[i].l,b[i].r,1);
if(re>=1) {
update(1,n,b[i].l,b[i].r,-1,1);
ans--;
}
}
printf("%d\n",ans);
}

BZOJ_1826_[JSOI2010]缓存交换 _线段树+贪心的更多相关文章

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

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

  2. BZOJ_3252_攻略_线段树+dfs序

    BZOJ_3252_攻略_线段树+dfs序 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏< ...

  3. BZOJ_1828_[Usaco2010 Mar]balloc 农场分配_线段树

    BZOJ_1828_[Usaco2010 Mar]balloc 农场分配_线段树 Description Input 第1行:两个用空格隔开的整数:N和M * 第2行到N+1行:第i+1行表示一个整数 ...

  4. 1826: [JSOI2010]缓存交换

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

  5. BZOJ_4636_蒟蒻的数列_线段树+动态开点

    BZOJ_4636_蒟蒻的数列_线段树+动态开点 Description 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个数列,初始值均为0,他进行N次操作,每次将 ...

  6. BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针

    BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针 Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间, ...

  7. BZOJ_2124_等差子序列_线段树+Hash

    BZOJ_2124_等差子序列_线段树+Hash Description 给一个1到N的排列{Ai},询问是否存在1<=p1<p2<p3<p4<p5<…<pL ...

  8. BZOJ_1798_[AHOI2009]维护序列_线段树

    BZOJ_1798_[AHOI2009]维护序列_线段树 题意:老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: ( ...

  9. BZOJ_3307_雨天的尾巴_线段树合并+树上差分

    BZOJ_3307_雨天的尾巴_线段树合并 Description N个点,形成一个树状结构.有M次发放,每次选择两个点x,y 对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成 所有发放后 ...

随机推荐

  1. 百度编辑器上传视频音频的bug

    前言:UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码,百度Ueditor 支持多种后台语言上传 ...

  2. 【读书笔记】C++Primer---第一章

    1.标准库的头文件用尖括号<>括起来,非标准库的头文件用双引号“”括起来:

  3. jvm垃圾回收(三)

    一.分代思想(年轻代.老年代.永久代): 1.一个新人(new对象)会优先在伊甸园(Eden区)出生,当伊甸园(Eden区)人口达到最大容量时,JVM会派MinorGC去看看哪些人还有价值 2.伊甸园 ...

  4. SQL Server Agent Job 多服务器管理

  5. Node笔记二

    ### 安装包的方式安装 - 安装包下载链接: + Mac OSX: [darwin](http://npm.taobao.org/mirrors/node/v5.7.0/node-v5.7.0.pk ...

  6. netcore入门-基础

    .NETCORE1.0出来了,咦不错,什么开源,跨平台的,观望下等2.0:我擦2.0出来了可以学习了,截止到目前2.1都快出来了,是时候学习一下了. 先建一个webapi项目,从简单的demo开始 l ...

  7. hadoop HA 详解

    NameNode 高可用整体架构概述 在 Hadoop 1.0 时代,Hadoop 的两大核心组件 HDFS NameNode 和 JobTracker 都存在着单点问题,这其中以 NameNode ...

  8. java I/O (一)

    java 的I/O类基本上可以分为6大类:二进制的输入,二进制的输出,文本的输入,文本的输出,FILTER类和其他对文件操作的工具类. Java的I/O类主要在java.io的包里,其中两个主要的流为 ...

  9. Django入门一之安装及项目创建

    1. 习惯性的创建虚拟环境 # 由于我安装也安装了pyhton3所以在前面要加python2 -m F:\Python Script\MyVirtualenv>python2 -m virtua ...

  10. windows下安装mysql-5.7.11-winx64

    1.解压.   2.将『D:\Program Files\mysql-5.7.11-winx64\bin』加入系统环境变量.   3.修改my-default.ini.   4.初始化data目录,在 ...