1. 程式人生 > >cache(STL)

cache(STL)

esp include hit col ont %d tro 根據 thml

cache

Description

栗醬在上操作系統原理這門課。

她遇到了一個內存管理的置換策略上的問題。

問題可以簡化成,有一個單線程程序,有nn步執行,每步執行需要調用第a_iai?個數據。不同的數據的大小相同。根據數據的大小,你被分配了mm頁內存,每頁內存可以裝取一個數據。

一開始所有的數據都在硬盤(虛擬內存)裏存儲。當程序需要調用第a_iai?個數據的時候,栗醬的老爺機需要使用整整11秒鐘把內存的數據移出,再從硬盤裏讀出數據,並覆蓋寫入到某一格內存中。

程序在每步執行過程中,需要調用的數據在內存中,位置不限,如果不在內存中,則花費時間需要從硬盤中讀入。

栗醬打算使用實現簡單的FIFO(先入先出)策略,即當內存不夠放的時候,優先把最早進來的刪掉,具體請參見樣例。

問按照栗醬采用的策略,在內存管理的置換上需要耗費多少時間。

Input

第一行為數據組數TT( T\le1000T1000 )。

每組數據第一行輸入兩個整數N,MN,M,分別代表程序的執行步數和被分配的內存的頁數。

1 \le N,M,a_i\le 1000001N,M,ai?100000

每組數據第二行包含NN個整數,a_iai?表示第ii步需要的數據。

數據保證\sum N\le 2,000,000N2,000,000

Output

對於每組數據輸出一行,即內存置換上花費的時間。

Sample Input 1

3
4 5
1 2 3 4
18 2
1 2 3 1 2 1 2 2 3 2 3 1 1 2 3 2 1 4
6 1
1 2 3 4 5 6

Sample Output 1

4
11
6

Hint

樣例1

因為內存一開始是空的,所以直接讀入即可。

樣例2

技術分享圖片

一開始移入11和22,在移入33的時候發現內存大小不足,所以按照先入先出順序移出11。

直到下劃線的第一個11時,發現此時內存裏有11和22,所以不需要移入,直接讀取即可。

所有下劃線位置的數據不需要導入,因為內存裏已經有了,以上共計為1111秒。

其中,被圈出的元素因為此時內存中只含有前面左邊的33和11,所以被迫移入並移除33。

樣例3

每次讀入都需要換出,所以需要花費66秒。

每次入隊時要用vis記錄某個數的個數 否則直接每次遍歷會超時

代碼:

#include <bits/stdc++.h>

using
namespace std; int main() { int T; scanf("%d",&T); while(T--) { int n,m; scanf("%d%d",&n,&m); queue<int> q; int vis[100005]={0}; int a[100005]; for(int i=0;i<n;i++) scanf("%d",&a[i]); int ans = 0; for(int i=0;i<n;i++) { if(vis[a[i]]) { // cout<<"*************"<<endl; continue; } else { if(q.size()<m) { q.push(a[i]); vis[a[i]] = 1; ans++; } else { vis[q.front()]=0; q.pop(); q.push(a[i]); vis[a[i]]=1; ans++; } } } printf("%d\n",ans); } return 0; }

cache(STL)