題目鏈接:[POI2005]SAM-Toy Cars
顯然每次,如果不在地面上,肯定直接把下一個距離最遠的放上去。
所以堆維護下一個最遠的距離即可。
但是要注意,如果當前在地面上,我們不用操作,但是我們要更新下一個的距離。由於是堆,不好更新,所以我們可以直接K++,再放一個當前的進去,或者把堆換成set、
AC代碼:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=5e5+10;
int vis[N],n,k,m,a[N],pos[N],b[N],cnt,res;
priority_queue<pair<int,int> > q;
signed main(){
cin>>n>>k>>m;
for(int i=1;i<=m;i++) scanf("%d",&a[i]);
for(int i=m;i>=1;i--){
if(!pos[a[i]]) b[i]=1e9;
else b[i]=pos[a[i]];
pos[a[i]]=i;
}
for(int i=1;i<=m;i++){
if(vis[a[i]]){k++; q.push({b[i],a[i]}); continue;}
if(q.size()<k){vis[a[i]]=1; q.push({b[i],a[i]}); res++; continue;}
auto u=q.top(); q.pop(); res++; vis[u.second]=0;
vis[a[i]]=1; q.push({b[i],a[i]});
}
cout<<res;
return 0;
}