详见https://ac.nowcoder.com/acm/contest/107/F?&headNav=www
解题思路:其实就是当内存不够,又有新的东西要放入时,就把内存中出现的下一个网页最远的给剔除内存。需要用优先队列来维护。具体思路就是每当提一个网页进入内存时,和它一样的下一个网页放入优先队列维护。如果这个网页已经没有下一个相同网页了,那直接提出好了。然后每次有新的网页要放入时,就把优先队列中最远的那个网页去除即可。
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
struct node
{
int id,u;
node(){
}
node(int id,int u):id(id),u(u){
}
};
priority_queue<node> q;
queue<int> s[50001];
int a[50001],ins[50001],cnt,ans;
bool operator<(node a,node b)
{
return a.id<b.id;
}
int main()
{
int n,m,g;
//freopen("t.txt","r",stdin);
while(scanf("%d%d%d",&n,&m,&g)!=EOF)
{
for(int i=1;i<=m;i++)
while(!s[i].empty()) s[i].pop();
memset(ins,0,sizeof(ins));
for(int i=0;i<g;i++)
{
scanf("%d",&a[i]);
s[a[i]].push(i);
}
ans=0;cnt=0;
for(int i=0;i<g;i++)
{
if(!ins[a[i]])
{
ans++;
if(cnt<n)
{
ins[a[i]]=1;
if(!s[a[i]].empty()) s[a[i]].pop();
if(s[a[i]].empty())
{
ins[a[i]]=0;
}else
{
cnt++;
q.push(node(s[a[i]].front(),a[i]));
}
}
else
{
node t=q.top();
q.pop();
ins[t.u]=0;
if(!s[a[i]].empty()) s[a[i]].pop();
if(!s[a[i]].empty())
{
q.push(node(s[a[i]].front(),a[i]));
ins[a[i]]=1;
}else
{
cnt--;
}
}
}
}
printf("%d\n",ans);
}
return 0;
}