J. LRU
-
用 s e t set set 维护 d d d 个互不相同的元素,添加新元素时,将最先入 s e t set set 的元素丢弃
因此, s e t set set 要重载排序,就相当于之前解法的 q u e u e + s e t queue+set queue+set 合并了
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
struct Node
{
int id,val;
bool operator < (const Node &b) const { return id<b.id; }
};
map <int,int> ma,mp;
set <Node> se;
int a[N];
bool check(int d,int n,int k)
{
int tot=0;
mp.clear();
se.clear();
for(int i=1;i<=n;i++)
{
if(mp[a[i]])
{
tot++;
se.erase({mp[a[i]],a[i]}); //去掉旧的
}
else
{
if(se.size()==d)
{
Node t=*se.begin();
se.erase(se.begin());
mp.erase(t.val);
}
}
mp[a[i]]=i; // mp维护当前元素的pre下标
se.insert({i,a[i]});
}
return tot>=k;
}
signed main()
{
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)
{
cin>>a[i];
ma[a[i]]++;
}
int cnt=0;
// 计算所有可能的 hit
for(int i=1;i<=n;i++)
{
if(ma[a[i]]>1)
{
cnt+=ma[a[i]]-1;
ma[a[i]]=0;
}
}
if(cnt<k)
{
cout<<"cbddl"<<endl;
return 0;
}
int l=1,r=n,ans=0;
while(l<=r)
{
int mid=l+r>>1;
if(check(mid,n,k))
{
r=mid-1;
ans=mid;
}
else l=mid+1;
}
cout<<ans<<endl;
}