zoukankan      html  css  js  c++  java
  • poj3261

    后缀数组+单调队列

    注意:后缀数组的所有后缀中包括空串,因此有strlen(s)+1个后缀。

    View Code
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    using namespace std;
    
    #define N 20005
    
    struct Elem
    {
        int pos, value;
        Elem()
        {}
        Elem(int pp, int vv): pos(pp), value(vv)
        {}
    }q[N];
    
    int n, m;
    int s[N];
    // N > 256
    int sa[N], height[N], rank[N], tmp[N], top[N];
    
    void input()
    {
        scanf("%d%d", &n, &m);
        for (int i = 0; i < n; i++)
            scanf("%d", &s[i]);
    }
    
    void makesa(int n)
    {
        // O(N * log N)
        int i, j, len, na;
        na = (n < 256 ? 256 : n);
        memset(top, 0, na * sizeof(int));
        for (i = 0; i < n; i++)
            top[rank[i] = s[i] & 0xff]++;
        for (i = 1; i < na; i++)
            top[i] += top[i - 1];
        for (i = 0; i < n; i++)
            sa[--top[rank[i]]] = i;
        for (len = 1; len < n; len <<= 1)
        {
            for (i = 0; i < n; i++)
            {
                j = sa[i] - len;
                if (j < 0)
                    j += n;
                tmp[top[rank[j]]++] = j;
            }
            sa[tmp[top[0] = 0]] = j = 0;
            for (i = 1; i < n; i++)
            {
                if (rank[tmp[i]] != rank[tmp[i - 1]] || rank[tmp[i] + len]
                        != rank[tmp[i - 1] + len])
                    top[++j] = i;
                sa[tmp[i]] = j;
            }
            memcpy(rank, sa, n * sizeof(int));
            memcpy(sa, tmp, n * sizeof(int));
            if (j >= n - 1)
                break;
        }
    }
    
    void lcp(int n)
    {
        // O(4 * N)
        int i, j, k;
        for (j = rank[height[i = k = 0] = 0]; i < n - 1; i++, k++)
            while (k >= 0 && s[i] != s[sa[j - 1] + k])
                height[j] = (k--), j = rank[sa[j] + 1];
    }
    
    void push(Elem a, int front, int &rear)
    {
        while (rear > front && a.value <= q[rear - 1].value)
            rear--;
        q[rear++] = a;
    }
    
    int work()
    {
        int front = 0, rear = 0;
        for (int i = 1; i < m; i++)
            push(Elem(i, height[i]), front, rear);
        int ret = q[front].value;
        for (int i = m; i <= n; i++)
        {
            while (front != rear && q[front].pos <= i - m + 1)
                front++;
            push(Elem(i, height[i]), front, rear);
            ret = max(ret, q[front].value);
        }
        return ret;
    }
    
    int main()
    {
        //freopen("t.txt", "r", stdin);
        input();
        makesa(n + 1);
        lcp(n + 1);
        printf("%d\n", work());
        return 0;
    }
  • 相关阅读:
    服务返返回状态码详解
    LeetCode#28 Implement strStr()
    LeetCode#58 Length of Last Word
    LeetCode#66 Plus One
    spooling技术
    文件的打开与关闭
    DMA方式与通道方式
    中断向量、向量中断、向量地址
    中断响应优先级和中断处理优先级
    I/O接口
  • 原文地址:https://www.cnblogs.com/rainydays/p/2577706.html
Copyright © 2011-2022 走看看