• BZOJ4837:[Lydsy1704月赛]LRU算法(双指针&模拟)


    Description

    小Q同学在学习操作系统中内存管理的一种页面置换算法,LRU(LeastRecentlyUsed)算法。
    为了帮助小Q同学理解这种算法,你需要在这道题中实现这种算法,接下来简要地介绍这种算法的原理:
    1.初始化时,你有一个最大长度为n的空队列,用于暂时存储一些页面的地址。
    2.当系统需要加载一个不在队列中的页面时,如果队列已满,则弹出队首元素,并将需要加载的页面加到队尾,
    否则直接将需要加载的页面加到队尾。
    3.当系统需要加载一个在队列中的页面时,将该页面移至队尾。
    在这道题中,小Q同学需要处理有q个请求,每个请求会给定一个整数x,表示系统需要加载地址为x的页面,
    而你需要在每个请求完成后给出整个队列中页面的地址之和。为了便于计算,设第i个请求给出的整数为x_i,
    第i个请求后你给出的答案为y_i,则对于1<i≤q有x_i=(A*x_(i-1)+B)modp,其中x_1,A,B,p是给
    定的整数,并且你只需要输出sigma(i*y_i),1<=i<=Q对2^64取模的值,而不是每个y_i。

    Input

    第一行包含一个正整数T,表示有T组数据,满足T≤20。
    接下来依次给出每组测试数据。对于每组测试数据:
    第一行包含两个正整数n和q,满足1≤n≤10^5,1≤q≤10^6。
    第二行包含四个整数x_1,A,B和p,满足0≤x_1,A,B<p,1≤p≤10^6+3。

    Output

     对于每组测试数据,输出一行一个非负整数,表示这组数据的答案。

    Sample Input

    2
    5 10
    0 1 1 5
    5 10
    0 1 1 10

    Sample Output

    485
    1135

    思路:加入X,如果X不存在队列,当队列里小于N个,直接加到队尾;否则删去队首删去队尾。 如果X存在队里,那么移到队尾。  我们发现用队列不方便模拟,因为无法删去中间的数,而set来操作又会超时。   因为我们维护的是一个长度为N的窗口,可以用双指针来模拟。 维护一个队列q,如果q[i]=-1,说明位置i已经被删去。同时维护一个pos数组保保存其在队列的位置。 最后用一个队首head来维护现在删到了哪里。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=2000010;
    ll a[maxn],A,B,P; int q[maxn],pos[maxn],cnt,head,num;
    unsigned long long ans,res;
    int main()
    {
        int T,N,Q;
        scanf("%d",&T);
        while(T--){
            cnt=0; ans=0; res=0; head=1; num=0;
            scanf("%d%d",&N,&Q);
            scanf("%lld%lld%lld%lld",&a[1],&A,&B,&P);
            for(int i=2;i<=Q;i++) a[i]=(A*a[i-1]+B)%P;
            for(int i=1;i<=Q;i++) pos[a[i]]=-1;
            for(int i=1;i<=Q;i++){
                if(pos[a[i]]==-1){
                    if(num<N) {
                        num++;
                        pos[a[i]]=++cnt, q[cnt]=a[i],res+=a[i];
                    }
                    else {
                        while(q[head]==-1) head++;
                        pos[q[head]]=-1,res-=q[head],q[head]=-1;
                        pos[a[i]]=++cnt,q[cnt]=a[i],res+=a[i];
                    }
                }
                else {
                    q[pos[a[i]]]=-1,pos[a[i]]=++cnt,q[cnt]=a[i];
                }
                ans+=res*i;
            }
            cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    [HAOI2015]按位或——Min-Max容斥+FWT
    HDU 4773 Problem of Apollonius——圆反演
    类欧几里得小结
    线性规划(单纯形法)知识整理
    奇怪的数学题(51nod1847)——min_25筛+杜教筛+第二类斯特林数
    CSP-S 2019 游记
    2019.11.11~2019.11.12考试总结
    2019.11.6~2019.11.7考试总结
    1019.11.1~2019.11.2考试总结
    Final-阶段站立会议4
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9956776.html
Copyright © 2020-2023  润新知