• LRU Algorithm Gym


    LRU Algorithm

    [Time Limit: 1000 msquad Memory Limit: 524288 kB ]

    题意

    给出 (n) 个数字和 (m) 次查询。
    每次询问中,给出 (L) 表示 (LRU) 中缓存器的大小,再给出 (L) 个数字,问对 (n) 个数字做大小为 (L)(LRU) 过程中,会不会有某一时刻,缓存器中的数字序列和给出的 (L) 个数字一致。

    思路

    首先对于 (LRU) 算法,当缓存器大小为 (L)时,以某个位置 (pos) 结束的缓存器中的元素,本质上就是从 (pos) 往前的 (L) 个第一次出现的不同的数字。所以每次查询我们只要想办法找出以每个位置结束,往前 (L) 个不同的数字是什么,然后判断和所查询的序列是否一致,就可以知道是 (Yes) 或者是 (No) 了。

    首先发现 (n=5000),那么可以 (n^2) 暴力预处理出 (has[i][j]),表示从 (i) 开始,往前 (j) 个不同的数字所构成的 (hash) 值,然后只要判断给出的 (L) 个数字的 (hash) 值是否满足条件就可以了。注意判断一下不满 (L) 个元素的情况,那就还要求找到的 (pos) 位置以前只存在给出的数字。

    /*************************************************************** 
    	> File Name		: L.cpp
    	> Author		: Jiaaaaaaaqi
    	> Created Time	: Tue 12 Nov 2019 04:58:09 PM CST
     ***************************************************************/
    
    #include <map>
    #include <set>
    #include <list>
    #include <ctime>
    #include <cmath>
    #include <stack>
    #include <queue>
    #include <cfloat>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <bitset>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <unordered_map>
    #define  lowbit(x)  x & (-x)
    #define  mes(a, b)  memset(a, b, sizeof a)
    #define  fi         first
    #define  se         second
    #define  pb         push_back
    #define  pii        pair<int, int>
    
    typedef unsigned long long int ull;
    typedef long long int ll;
    const int    maxn = 5e3 + 10;
    const int    maxm = 1e5 + 10;
    const ll     mod  = 1e9 + 7;
    const ll     INF  = 1e18 + 100;
    const int    inf  = 0x3f3f3f3f;
    const double pi   = acos(-1.0);
    const double eps  = 1e-8;
    using namespace std;
    
    int n, m;
    int cas, tol, T;
    
    int aa[maxn];
    int a[maxn], b[maxn];
    int vis[maxn], pre[maxn];
    ull has[maxn][maxn], seed = 233;
    
    int main() {
    	// freopen("in", "r", stdin);
    	scanf("%d", &T);
    	while(T--) {
    		scanf("%d%d", &n, &m);
    		for(int i=1; i<=n; i++)	scanf("%d", &aa[i]);
    		int len1 = 0, len2 = 0;
    		for(int i=1; i<=n; i++) {
    			if(n==0 || aa[i]!=a[len1])	a[++len1] = aa[i];
    		}
    		for(int i=1; i<=n; i++)	vis[i] = pre[i] = 0;
    		for(int i=1; i<=n; i++) {
    			pre[i] = pre[i-1];
    			if(vis[a[i]] == 0)	pre[i]++;
    			vis[a[i]]++;
    		}
    		for(int i=n; i>=1; i--) {
    			for(int j=1; j<=n; j++)	vis[j] = 0;
    			int cnt = 0;has[i][0] = 0;
    			for(int j=i; j>=1; j--) {
    				if(vis[a[j]] == 0) {
    					cnt++;
    					has[i][cnt] = has[i][cnt-1] * seed + a[j];
    				}
    				vis[a[j]]++;
    			}
    		}
    		while(m--) {
    			scanf("%d", &len2);
    			for(int i=1; i<=len2; i++)	scanf("%d", &b[i]);
    			bool flag = 0;
    			while(len2 && b[len2] == 0)	len2--, flag = 1;
    			if(len2 == 0) {
    				printf("Yes
    ");
    				continue;
    			}
    			ull ans = 0;for(int i=1; i<=len2; i++)	ans = ans*seed+b[i];
    			int pos = 0;
    			for(int i=1; i<=len1; i++) {
    				if(has[i][len2] == ans) {
    					pos = i;
    					break;
    				}
    			}
    			if(pos && (!flag || (flag && pre[pos]==len2)))	printf("Yes
    ");
    			else	printf("No
    ");
    		}
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    自定义注解!绝对是程序员装逼的利器!!
    我女儿说要看雪,但是我家在南方,于是我默默的拿起了键盘,下雪咯。
    零基础转行前端,如何拿下了字节跳动、美团等大厂offer
    “TensorFlow 开发者出道计划”全攻略,玩转社区看这里!
    web面试必问的题
    Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate)
    520了,用32做个简单的小程序
    虚拟机找不到本机vmnet0,vmnet8,无法连接xshell,解决方案
    Linux用户登出之后保持后台进程(nohup)
    Debian取消从光盘安装软件的方式(please insert the disc labeled)
  • 原文地址:https://www.cnblogs.com/Jiaaaaaaaqi/p/11971234.html
Copyright © 2020-2023  润新知