https://ac.nowcoder.com/acm/contest/883/J
LRU,操作系统中的最近最常使用算法
#include<bits/stdc++.h>
#define MAXN 1000005
#define ll long long
using namespace std;
struct node{
int key;
int pre;
int nxt;
}cash[MAXN<<1];//模拟链表 表示存储单元
unordered_map<ll,int> ft;//哈希表映射 把地址规模缩小
unordered_set<int> st;//类似于操作系统的快表
int stl;
int total;//哈希表总长 首地址0与尾地址1都用过 所以从2开始
int head,tail;//链表头尾
void ins(int add){
st.insert(add);
int preadd=cash[tail].pre;//尾端节点的地址
cash[preadd].nxt=add;
cash[add].pre=preadd;
cash[add].nxt=tail;
cash[tail].pre=add;//模拟链表
}
void del(int add){
st.erase(add);
cash[cash[add].pre].nxt=cash[add].nxt;
cash[cash[add].nxt].pre=cash[add].pre;
}
int n,m;
int main(){
int pa;
cin>>pa;
while(pa--){
ft.clear();st.clear();
stl=0;total=2;
head=0;tail=1;
cash[head].nxt=tail;
cash[tail].pre=head;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
int opt,v;
char s[20];
scanf("%d%s%d",&opt,s,&v);
ll ladd=0;
for(int j=0;j<strlen(s);j++){
ladd=10*ladd+s[j]-'0'+1;
}//使用一种哈希构造方法 因为0与00及000都是不同的地址
if(opt==0){
if(ft.find(ladd)==ft.end()){
ft[ladd]=total++;
}
int add=ft[ladd];//映射后的新地址
if(st.find(add)==st.end()){
cash[add].key=v;
ins(add);
stl++;
if(stl>m){
del(cash[head].nxt);//从头节点删除
stl--;
}
}
else{
del(add);
ins(add);
}
printf("%d\n",cash[add].key);
}
else {
if(ft.find(ladd)==ft.end()){
puts("Invalid");
continue;
}
int add=ft[ladd];
if(st.find(add)==st.end()){
puts("Invalid");
continue;
}
int ad=add;
switch(v){
case 1:ad=cash[ad].nxt;break;
case -1:ad=cash[ad].pre;break;
}
if(ad==head||ad==tail)puts("Invalid");
else printf("%d\n",cash[ad].key);
}
}
}
return 0;
}