zoukankan      html  css  js  c++  java
  • [CCPC2019 哈尔滨] L. LRU Algorithm

    [CCPC2019 哈尔滨] L. LRU Algorithm

    Description

    对一个序列执行 LRU 算法。每次询问给定一个窗口,问它是否出现过。

    Solution

    很显然我们可以先假设窗口长度无限,匹配时候只匹配前缀就可以了。

    然后我准备用普通 HASH 莽过去,发现凉了。

    首先可以不使用 HASH 表,而对每个长度存下它的所有 HASH 值,然后暴力枚举看是否相等。

    这样的好处就是相等以后可以找到原序列然后确定一下是否真的相等,简称二次判断。

    虽然复杂度玄学,但还是 (982ms) 卡过去了。

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int M = 5003, MOD = 1000000007;
    int t[M],q[M][M],T,n,p,m;
    ll h[M][M],val;
    int main() {
        scanf("%d",&T);
        while(T--) {
            scanf("%d%d",&n,&p);
            for(int i=0;i<=n;i++) {
                for(int j=0;j<=n;j++) {
                    q[i][j]=h[i][j]=0;
                }
            }
            int top=0;
            for(int i=1;i<=n;i++) {
                for(int j=1;j<=n;j++) q[i][j]=q[i-1][j];
                int tmp,pos=0;
                scanf("%d",&tmp);
                for(int j=1;j<=top;j++) {
                    if(tmp==q[i][j]) {
                        pos=j;
                        break;
                    }
                }
                if(pos) {
                    for(int j=pos;j;j--) q[i][j]=q[i][j-1];
                }
                else {
                    for(int j=++top;j;j--) q[i][j]=q[i][j-1];
                }
                q[i][1]=tmp;
                for(int j=1;j<=n;j++) h[i][j]=(h[i][j-1]*(n+1)+q[i][j])%MOD;
            }
            while(p--) {
                scanf("%d",&m);
                val=0;
                for(int i=1;i<=m;i++) {
                    scanf("%d",&t[i]);
                    val=(val*(n+1)+t[i])%MOD;
                }
                int flag=0;
                for(int i=0;i<=n;i++) {
                    if(h[i][m]==val) {
                        int fg=1;
                        for(int j=1;j<=m;j++) {
                            if(q[i][j]!=t[j]) {
                                fg=0;
                                break;
                            }
                        }
                        if(fg) {
                            flag=1;
                            break;
                        }
                    }
                }
                puts(flag?"Yes":"No");
            }
        }
    }
    
    /*
    1
    7 5
    4 3 4 2 3 1 4
    1 4
    2 2 3
    3 3 2 1
    4 4 1 3 2
    4 3 4 0 0
    */
    
  • 相关阅读:
    2018全球最强物联网公司榜单揭晓
    物联网
    kalman滤波
    自动驾驶
    CAN总线基础
    Linux系统下x86和ARM的区别有哪些?
    算法课笔记系列(七)—— 平摊分析Amortized Analysis
    深入理解Linux内存分配
    linux内核--自旋锁的理解
    DMA(直接存储器存取)
  • 原文地址:https://www.cnblogs.com/mollnn/p/11810063.html
Copyright © 2011-2022 走看看