【BZOJ4837】LRU算法 [模拟]

LRU算法

Time Limit: 6 Sec  Memory Limit: 128 MB
[Submit][Status][Discuss]

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,满足。
  第二行包含四个整数x_1,A,B和p,满足。

Output

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

Sample Input

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

Sample Output

  485
  1135

HINT

  1≤n≤10^5, 1≤q≤10^6
  0≤x_1,A,B<p, 1≤p≤10^6+3

Main idea

  队列元素个数上限为n。每次加入一个元素x,
  1.如果x不在队列中:
    1.如果队列没满,把x放在队尾;
    2.如果队列元素满了,把队头删掉,x放在队尾。
  2.如果x在队列中:
    把x删掉,把x扔到队尾。

  定义val为当前队列中所有元素和,求Σi*val。

Solution

  直接用数组模拟即可,我们设定PD[i]表示 i 这个位置是否有元素pos[i]表示元素 i 所在的位置,然后用一个 q 表示当前队列

  那么显然删除队头的话,只要删除当前第一个有元素的位置,加入的话扔在队尾即可。

  中间用num、val记录元素个数以及元素和即可。

  (至于对2^64取模,就是unsigned long long自然溢出即可。)

Code

 1 #include<iostream>  
 2 #include<string>  
 3 #include<algorithm>  
 4 #include<cstdio>  
 5 #include<cstring>  
 6 #include<cstdlib>  
 7 #include<cmath>
 8 #include<vector>
 9 using namespace std; 
10 typedef unsigned long long ull;
11  
12 const int ONE = 1e5+5;
13 const int INF = 2147483640;
14  
15 int T;
16 int n,m;
17 int x,A,B,p;
18 int PD[10000001],pos[10000001];
19 int q[10000001];
20 int Ans;
21  
22 inline int get()
23 {
24         int res=1,Q=1;  char c;
25         while( (c=getchar())<48 || c>57)
26         if(c=='-')Q=-1;
27         if(Q) res=c-48; 
28         while((c=getchar())>=48 && c<=57) 
29         res=res*10+c-48;
30         return res*Q; 
31 }
32  
33 void Solve()
34 {
35         n=get();    m=get();
36         x=get();    A=get();    B=get();    p=get(); 
37         ull Ans = 0, val = 0;
38         int tou=1, wei=0, num=0;
39          
40         for(int i=1;i<=max(n,m);i++) PD[i] = 0;
41         for(int i=0;i<=p;i++) pos[i] = 0;
42         for(int i=1;i<=m;i++)
43         {
44             if(!pos[x])
45             {
46                 if(num == n)
47                 {
48                     while(!PD[tou]) tou++;
49                     pos[q[tou]] = 0;    PD[tou] = 0;
50                     val -= q[tou];  num--;
51                 }
52                 q[++wei] = x; 
53                 pos[x] = wei; PD[wei] = 1;
54                 val+=x; num++;
55             }
56              
57             else
58             {
59                 q[++wei] = x;
60                 PD[pos[x]] = 0; pos[x] = wei; PD[pos[x]] = 1;
61             }
62              
63             x = ((long long)A*x%p + B) % p;
64             Ans += i*val; 
65         }
66          
67         cout<<Ans<<endl;
68 }
69  
70 int main()
71 {
72         T=get();
73         while(T--)
74             Solve();
75 }
View Code
原文地址:https://www.cnblogs.com/BearChild/p/6746416.html