BZOJ 1206 [HNOI2005]虚拟内存:模拟

Posted Leohh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 1206 [HNOI2005]虚拟内存:模拟相关的知识,希望对你有一定的参考价值。

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1206

题意:

  内存大小为n(外存无限大),共有m次访问,每一次访问的信息编号为p。

  对于每一条信息,不在内存中,就在外存中。

  内存和外存的访问速度不同。为了提高整体的访问速度,有这样一种内存管理的算法:

    (1)如果p在内存中,直接访问,算法结束。否则转步骤(2)。

    (2)如果内存有剩余空间,则将p由外存转移到内存中来,算法结束。否则转步骤(3)。

    (3)选出内存中访问次数最少的一条信息(访问次数相同选进入内存时间早的),用p将它替换掉,算法结束。

  访问次数是指:某条信息从进入内存的那一刻开始一直到现在的访问次数。(如果之前进入过内存,然后又被替换掉了,那么之前的访问次数不算)

  问你在内存中直接访问到p的次数。(即执行步骤(1)的次数)

 

题解:

  模拟。

  用STL中map和set神器~~~

 

  map映射:p的编号idx -> (p的访问次数cnt, p进入内存的时间tim)

  set:(idx, cnt, tim) 排序优先级:先cnt,后tim。(均取小)

 

  map用来查询p是否在内存中,以及有关p的信息(以便在set中定位到相应元素)

  set用来作优先队列(可任意插入和删除元素),队首为内存中访问次数最少(或进入内存最早)的一条信息。

 

  map和set分别保证了在log(N)时间内的查找和删除(替换)信息。

  总复杂度为O(m * log(n))。

 

AC Code:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <map>
 5 #include <set>
 6 
 7 using namespace std;
 8 
 9 struct Pro
10 {
11     int idx;
12     int cnt;
13     int tim;
14     Pro(int _idx,int _cnt,int _tim)
15     {
16         idx=_idx;
17         cnt=_cnt;
18         tim=_tim;
19     }
20     Pro(){}
21     friend bool operator < (const Pro &a,const Pro &b)
22     {
23         return a.cnt!=b.cnt?a.cnt<b.cnt:a.tim<b.tim;
24     }
25 };
26 
27 int n,m,p;
28 int ans=0;
29 map<int,pair<int,int> > mp;
30 set<Pro> st;
31 
32 int main()
33 {
34     cin>>n>>m;
35     for(int i=0;i<m;i++)
36     {
37         cin>>p;
38         map<int,pair<int,int> >::iterator it_mp=mp.find(p);
39         if(it_mp!=mp.end())
40         {
41             int cnt=(it_mp->second).first;
42             int tim=(it_mp->second).second;
43             st.erase(Pro(p,cnt,tim));
44             st.insert(Pro(p,cnt+1,tim));
45             mp[p]=pair<int,int>(cnt+1,tim);
46             ans++;
47         }
48         else if(mp.size()<n)
49         {
50             mp.insert(pair<int,pair<int,int> >(p,pair<int,int>(1,i)));
51             st.insert(Pro(p,1,i));
52         }
53         else
54         {
55             set<Pro>::iterator it_st=st.begin();
56             int idx=it_st->idx;
57             int cnt=it_st->cnt;
58             int tim=it_st->tim;
59             mp.erase(idx);
60             st.erase(it_st);
61             mp.insert(pair<int,pair<int,int> >(p,pair<int,int>(1,i)));
62             st.insert(Pro(p,1,i));
63         }
64     }
65     cout<<ans<<endl;
66 }

 

以上是关于BZOJ 1206 [HNOI2005]虚拟内存:模拟的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1202 [HNOI2005]狡猾的商人

[BZOJ1202][HNOI2005]狡猾的商人

BZOJ 1202 [HNOI2005]狡猾的商人

BZOJ-1202: [HNOI2005]狡猾的商人 (并查集+前缀和)

bzoj1202 HNOI2005—狡猾的商人

bzoj 1202: [HNOI2005]狡猾的商人 并查集好题