LRU management(模拟数据结构)

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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值