BZOJ1206:[HNOI2005]虚拟内存
我对模拟的理解:https://www.cnblogs.com/AKMer/p/9064018.html
题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1206
上周因为一些原因脑子不是很好用,然后上周从没做到过一遍\(A\)题。然后这周一来学校就感冒了……室友晚上睡觉打喷嚏飞我一脸……然后脑子晕乎乎的……
但是我居然一遍\(A\)了??

简直假爆了(虽然我觉得用线段树的话一遍\(A\)应该很正常才对……换Splay可能就得GG)。
首先,我们先将数据离线读入,然后离散化,因为\(P_i\leqslant10^9\)
然后我们种一颗线段树,线段树\(n\)个叶子结点就是内存的\(n\)个页面,对于每个结点,我们都记录它所对应区间的满足题意要求的“最小值”(就是假如有一个新访问需要替换原有的位置,应该被替换的的位置,空白页也算)在线段树里的位置,访问次数,最早进来的时间还有离散化后的页编号(初始为inf)。还要记录对于每个页它在线段树里对应哪个叶子结点(如果没有在线段树里就是0)。然后对于每个询问,我们根据题意模拟:
如果该询问页在线段树里,直接从叶子一路往上跟新信息。
如果它不在,那么就找整个内存里的“最小值”,并且用该询问的信息替换掉。
时间复杂度:\(O(mlogn)\)
空间复杂度:\(O(m+n)\)
代码如下:
#include <cstdio>
#include <algorithm>
using namespace std;
const int inf=2e9;
const int maxn=1e5+5,maxm=1e6+5;
int inseg[maxm];//insge[v]表示v号页在线段树的叶节点的编号是多少
int n,m,ans,cnt;
int read() {
	int x=0,f=1;char ch=getchar();
	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<1)+(x<<3)+ch-'0';
	return x*f;
}
struct page {
	int v,id,rk;
}a[maxm];
bool cmp_v(page a,page b) {
	return a.v<b.v;//按照v从大到小排序
}
bool cmp_id(page a,page b) {
	return a.id<b.id;//按照id从大到小排序
}
struct treenode {
	int tot,tim,pos,v;
	bool operator <(const treenode &a)const {
		if(tot==a.tot)return tim<a.tim;
		return tot<a.tot;//访问次数为第一关键字,进入内存时间为第二关键字
	}
};
struct segment_tree {
	treenode tree[maxn*4];
	void update(int p) {
		if(tree[p<<1]<tree[p<<1|1])tree[p]=tree[p<<1];
		else tree[p]=tree[p<<1|1];//哪边的替换优先级更高就用哪边更新父亲
	}
	void build(int p,int l,int r) {
		if(l==r) {
			tree[p].tot=tree[p].tim=0;
			tree[p].v=inf,tree[p].pos=l;//初始的页都是inf页,然后都是访问过0次的
			return;
		}
		int mid=(l+r)>>1;
		build(p<<1,l,mid);
		build(p<<1|1,mid+1,r);
		update(p);
	}
	void add(int p,bool isleave) {
		if(isleave)tree[p].tot++;//如果是叶子结点直接加一次访问数
		else update(p);//不然就更新自己的信息,因为他的子树信息更新了
		if(p==1)return;//到根节点就直接return
		add(p>>1,0);//去更新父亲结点
	}
	void change(int p,int l,int r,int T,int v) {
		if(l==r) {
			if(tree[p].v!=inf)inseg[tree[p].v]=0;//把原先占据该结点的页信息抹掉
			inseg[v]=p;
			tree[p].v=v;
			tree[p].tot=1;
			tree[p].tim=T;//更新该结点
			return;
		}
		int mid=(l+r)>>1;
		if(tree[p].pos<=mid)change(p<<1,l,mid,T,v);
		else change(p<<1|1,mid+1,r,T,v);//找“最小值”去change
		update(p);
	}
}T;
int main() {
	n=read(),m=read();a[0].v=inf;
	for(int i=1;i<=m;i++)
		a[i].id=i,a[i].v=read();
	sort(a+1,a+m+1,cmp_v);
	for(int i=1;i<=m;i++)
		if(a[i].v==a[i-1].v)a[i].rk=cnt;
		else a[i].rk=++cnt;
	sort(a+1,a+m+1,cmp_id);//离散化
	T.build(1,1,n);//建树
	for(int i=1;i<=m;i++) {
		if(inseg[a[i].rk])T.add(inseg[a[i].rk],1),ans++;//如果该询问存在于内存中就增加访问次数
		else T.change(1,1,n,i,a[i].rk);//否则替换掉一个符合要求的页
	}
	printf("%d\n",ans);
	return 0;
}
												
											BZOJ1206:[HNOI2005]虚拟内存的更多相关文章
- 1206: [HNOI2005]虚拟内存 - BZOJ
		
Description 操作系统中一种重要的存储管理技术就是虚拟内存技术.操作系统中允许进程同时运行,也就是并行.每个进程都有其相对独立的数据块(进程运行的过程中将对其进行读写操作).理想的情况下,这 ...
 - BZOJ 1206 [HNOI2005]虚拟内存:模拟
		
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1206 题意: 内存大小为n(外存无限大),共有m次访问,每一次访问的信息编号为p. 对于每 ...
 - BZOJ-1206   虚拟内存     Hash+离散化+Priority_Queue
		
闻说HNOI每年都有一道Hash. 1206: [HNOI2005]虚拟内存 Time Limit: 50 Sec Memory Limit: 162 MB Submit: 330 Solved: 2 ...
 - bzoj AC倒序
		
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
 - linux的虚拟内存是4G,而每个进程都有自己独立的4G内存空间,怎么理解?
		
问: linux的虚拟内存是4G,而每个进程都有自己独立的4G内存空间,怎么理解? 每个进程所拥有的4G独立的虚拟内存空间是什么意思?linux系统的虚拟4G空间中,高位的1G是用于系统内核运行的,那 ...
 - win7系统c盘瘦身,去虚拟内存方式
		
电脑使用过程中,C盘出现个情况,c盘属性上的大小 > c盘内容加起来的大小 原因就是"虚拟内存"在作祟. 运行 powercfg -h off 关闭系统休眠,删除C盘 hi ...
 - Mac Pro 8G 安装MyEclipse提示虚拟内存为0 安装失败
		
看的一个大神的博客,一句话解决了.哈哈 百度一下很多人都说开多一点程序,让程序占满内存,使其虚拟内存使用就能通过这一步骤,但这里有个更好一点的方案 通过执行: memory_pressure -l ...
 - netty4虚拟内存不断飙升
		
去年升级过一个老的netty3的程序到netty4,近期突然注意到一个问题,就是这个程序随着时间虚拟内存会不断升高.之前升级的时候担心存在内存泄露,所以还特意用jstate跟踪过gc回收的情况,并没有 ...
 - Mac Pro 16G 安装MyEclipse提示虚拟内存(为0)不够
		
百度一下很多人都说开多一点程序,让程序占满内存,使其虚拟内存使用就能通过这一步骤,但这里有个更好一点的方案 通过执行: memory_pressure -l critical 用系统内存压力测试进程占 ...
 
随机推荐
- Hadoop DataNode 节点的动态添加和动态删除
			
动态添加 DataNode 节点 hadoop环境是必须的 需要加入新的 DataNode 节点,前提是已经配置好 SSH 无密登录:直接复制已有DataNode中.ssh目录中的authorized ...
 - POJ 1584 A Round Peg in a Ground Hole【计算几何=_=你值得一虐】
			
链接: http://poj.org/problem?id=1584 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22013#probl ...
 - The hidden layers are either convolutional, pooling or fully connected.
			
https://en.wikipedia.org/wiki/Convolutional_neural_network Convolutional layers apply a convolution ...
 - linux shell脚本: 自动监控网站状态并发送提醒邮件
			
1.创建监控脚本:$ vi /alidata/shell/webcheck.sh #!/bin/sh weblist="/alidata/shell/weblist.txt" my ...
 - 【python】-- RabbitMQ 安装、基本示例、轮询机制
			
RabbitMQ MQ全称为Message Queue, 是一种分布式应用程序的的通信方法,它是消费-生产者模型的一个典型的代表,producer往消息队列中不断写入消息,而另一端consumer则可 ...
 - ThoughtWorks(中国) 程序员读书雷达
			
ThoughtWorks(中国)程序员读书雷达 软件业的特点是变化.若要提高软件开发的技能,就必须跟上技术发展的步伐.埋首醉心于项目开发与实战,固然能够锤炼自己的开发技巧,却难免受限于经验与学识.世界 ...
 - Android Studio 1.1 使用介绍及导入 jar 包和第三方依赖库
			
导入 jar 包 导入 jar 包的方式非常简单,就是在项目中的 libs 中放入你需要导入的 jar 包,然后右键你的 jar 文件,选择“add as a library”即可在你的项目中使用这个 ...
 - python3保存一个网页
			
import requests res = requests.get("http://www.baidu.com") savefile = open("baidu.htm ...
 - python spark
			
http://blog.jobbole.com/86232/ 1. 安装lib 材料: spark : http://spark.apache.org/downloads.html hadoop : ...
 - python 3 面向过程编程
			
python 3 面向过程编程 核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就像设计好一条工业流水线,是一种机械式的思维方式. 1.优点:程序结构清晰,可以把复杂的问题简单化,流程 ...