J. LRU management (链表模拟)2019牛客暑期多校训练营(第三场)

本文详细解析了一种使用结构体数组模拟双向链表,并结合字典树优化查询效率的算法策略。通过具体题目,展示了如何处理CPU进程调度问题,包括插入、删除、更新操作及内存管理。强调了在特定场景下,传统数据结构结合创新优化手段的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这题我是喊着救命打完的,我保证这是我最后一次使用结构体数组模拟双向链表。最后时间是卡过去的

题目思路:

       当插入CPU时,要先判断里边有没有,如果有就进行Updata操作也就是把他拽出来放到最后边,Updata要判断两种情况就是他是第一个与他是最后一个的情况,然后如果CPU里头没有,那么就要判断是否里边已经够m个进程了,如果够了就删掉首部,再把这个插入尾部,反之直接插入。

        op==1的时候,判断存不存在即可。以后还是乖乖用list吧。

这里如果直接map字符串会超超时,题解说要加一个字典树,或者字符串哈希。

#include<bits/stdc++.h>
#include<unordered_map>
#define ll long long
using namespace std;
const int MAXN=5e5+5;
const int MAXM = 7.7e5+5;
struct node
{
    int id,val,pri,aft;
}C[MAXN];
int q,m,cnt=0,last,st=-1,sz=0;
int pos[MAXN],len,val1[MAXN];
int trie[MAXM][12],tot=1,ed[MAXM];
void IInsert(char *str)
{
    int len=strlen(str),p=1;
    for(int k=0;k<len;k++){
            //cout<<k<<endl;
        int ch=str[k]-'0';
        if(trie[p][ch]==0)trie[p][ch] = ++tot;
        p=trie[p][ch];
    }
    //cout<<p<<endl;
    ed[p]=++cnt;
}
int ask(char *str)
{
    int len=strlen(str),p=1;
    for(int k=0;k<len;k++){
        p=trie[p][str[k]-'0'];
        if(p==0)return 0;
    }
    return ed[p];
}
void Insert(int x,int val)
{
    ++len;sz++;
    if(st==-1)st=len;
    if(last!=-1)C[last].aft=len;
    C[len].pri=last;
    //cout<<last<<"+++++++++++++"<<C[1].pri<<endl;
    C[len].id=x;
    C[len].aft=-1;
    last=len;
    pos[x]=len;
    val1[x]=val;
}
void Erase(int ss)
{
    st=C[ss].aft;sz--;
    if(st==-1)return;
    C[st].pri=-1;
    int now=C[ss].id;
    pos[now]=-1;
    val1[now]=-1;
}
void Updata(int x)
{
    int va=val1[x];
    int aa=C[pos[x]].pri;
    int bb=C[pos[x]].aft;
    if(bb==-1)return ;
    if(aa==-1){
        Erase(st);
        Insert(x,va);
        return ;
    }
    int index=pos[x];
    aa=C[index].pri,bb=C[index].aft;
    C[aa].aft=bb;
    C[bb].pri=aa;
    C[index].aft=-1;
    C[index].pri=last;
    C[last].aft=index;
    last=index;
}
void print(int x)
{
    cout<<st<<"--------"<<endl;
    for(int i=1;i<=len;i++){
        cout<<C[i].id<<" * "<<C[i].pri<<" * "<<C[i].aft<<endl;
    }
    cout<<endl;
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&q,&m);
        //unordered_map<string ,int>mm;
        memset(pos,-1,sizeof(int)*(q+5));
        memset(trie,0,sizeof(trie));
        memset(ed,0,sizeof(ed));
        memset(val1,0x3f,sizeof(int)*(q+5));
       // mm.clear();
        cnt=0,last=-1,st=-1,sz=0;tot=1;
        len=0;
        for(int i=1;i<=q;i++){
            int op,val;
            char name[12];
            scanf("%d",&op);scanf("%s",name);scanf("%d",&val);
            if(op==0){
                int qq=ask(name);//cout<<" "<<qq<<"In"<<endl;
                if(!qq){
                    IInsert(name);
                }
                int now_id=(qq==0)?cnt:qq;
                if(sz<m){
                    if(pos[now_id]==-1){
                        Insert(now_id,val);
                        printf("%d\n",val);
                    }
                    else {
                        Updata(now_id);
                        printf("%d\n",val1[now_id]);
                    }
                }
                else {
                    if(pos[now_id]==-1){
                        Insert(now_id,val);
                        Erase(st);
                        printf("%d\n",val);
                    }
                    else{
                        Updata(now_id);
                        printf("%d\n",val1[now_id]);
                    }
                }
            }
            else {
                int now_id=ask(name);
                int now=pos[now_id];
                //cout<<now<<"***"<<now_id<<endl;
               // if(!now_id)
                //{
                 //   printf("Invalid\n");
               // }
                int x=now;
                if(x==-1){
                    printf("Invalid\n");
                    continue;
                }
                if(val==-1){
                    x=C[now].pri;
                    if(x==-1){
                        printf("Invalid\n");
                        continue;
                    }
                    x=C[x].id;
                }
                else if(val==1){
                    x=C[now].aft;
                    if(x==-1){
                        printf("Invalid\n");
                        continue;
                    }
                    x=C[x].id;
                }
                else if(val==0){
                    x=C[x].id;
                }
                printf("%d\n",val1[x]);
            }
            //print(st);
        }
    }
}
/*
10
11 3
0 01 1
0 02 2
0 04 4
0 05 5
1 01 0
1 05 0
1 05 1
0 06 6
1 06 -1
0 01 -1
1 01 0



8 3
0 0101010 1
0 0101011 2
1 0101010 1
0 1100000 3
0 0101011 -1
0 1111111 4
1 0101011 0
1 0101010 0


8 3
0 0101010 1
0 0101011 2
1 0101010 1
0 1100000 3
0 0101011 -1
0 1111111 4
1 0101011 -1
1 0101010 0

*/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值