zoukankan      html  css  js  c++  java
  • HDU 4749: Parade Show

    看大神代码,发现上交大神很棒的一个思路

    题意:

    在源数字串中找出尽量多的连续子串,要求子串任意两值的大小关系与目标串相同位置的值的大小关系相同。求源串能拿出的子串的最大数量。

    关键词:

    RK-Hash

    优点:

    O(k)时间完成匹配检查(关键在于他能O(1) 完成 所有 相同位 检查)

    方法:

    对于一个K值,用某个进制数来表示其位置。

            比如 123121 中 的值 1 最后表示成 100101。

            然后,对于目标串也RK-hash,对于某个值,只要比较这个数,就能知道是否相同位都相同了。

    代码留恋:

    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    const int N = 100005, K = 26;
    int a[N], b[N], n, m, k;
    unsigned long long phs[K], ahs[K], DEF;
    
    const unsigned long long base = 29;
    
    int main() {
        while (scanf("%d%d%d", &n, &m, &k) == 3) {
            for (int i = 0; i < n; ++i) {
                scanf("%d", a + i);
            }
            for (int i = 0; i < m; ++i) {
                scanf("%d", b + i);
            }
            DEF = 1;
            for (int i = 0; i < m - 1; ++i) {
                DEF *= base;
            }
            memset(phs, 0, sizeof(phs));
            memset(ahs, 0, sizeof(ahs));
            for (int i = 0; i < m; ++i) {
                for (int j = 0; j < k; ++j) {
                    phs[j] *= base;
                }
                phs[b[i] - 1] += 1; 
            } 
            vector<int> v;
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < k; ++j) {
                    ahs[j] *= base;
                }
                ahs[a[i] - 1] += 1;
                if (i >= m - 1) {
                    int t1 = k - 1, t2 = k - 1;  
                    bool sue = false;
                    while (true) {
                        while (t1 >= 0 && ahs[t1] == 0) {
                            --t1;
                        }
                        while (t2 >= 0 && phs[t2] == 0) {
                            --t2;
                        }
                        if (t1 == -1 && t2 == -1) {
                            sue = true;
                            break;
                        }
                        if (t1 == -1 || t2 == -1) {
                            break;
                        }
                        if (ahs[t1] != phs[t2]) {
                            break;
                        }
                        --t1, --t2;
                    }
                    if (sue) {
                        v.push_back(i - m + 1);
                    }
                    ahs[a[i - m + 1] - 1] -= DEF;
                }
            }
            int last = -m - 5, ans = 0;
            for (int i = 0; i < (int)v.size(); ++i) {
                if (v[i] < last + m) {
                    continue;
                } else {
                    last = v[i];
                    ++ans;
                }
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code

           

  • 相关阅读:
    xamp配置多域名站点
    POJ1611-The Suspects-ACM
    POJ2524-宗教问题-并查集-ACM
    POJ3274-牛的属性-HASH-ACM
    拓扑排序-DFS
    拓扑排序
    POJ1007-DNA Sorting-ACM
    POJ1258-Agri-Net-ACM
    wdcp-apache配置错误导致进程淤积进而内存吃紧
    wdcp-apache开启KeepAlive提高响应速度
  • 原文地址:https://www.cnblogs.com/shinecheng/p/3332326.html
Copyright © 2011-2022 走看看