zoukankan      html  css  js  c++  java
  • hdu1403 赤裸裸的后缀数组

    赤裸裸的后缀数组的应用啊。直接将两个串连起来(中间加一个比小写字母小的字符,我学大家,用的‘#’),求出height数组,找最大值即可(得排除两个后缀在同一端的情况)

    /*
     * hdu1403/win.cpp
     * Created on: 2013-5-20
     * Author    : ben
     */
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <set>
    #include <map>
    #include <stack>
    #include <string>
    #include <vector>
    #include <deque>
    #include <list>
    #include <functional>
    #include <numeric>
    #include <cctype>
    using namespace std;
    const int MAXN = 200010;
    // MAXN > 256
    char s[MAXN];
    int sa[MAXN], height[MAXN], rank[MAXN], h[MAXN];
    int tmp[MAXN], top[MAXN];
    int N;
    void makesa() { // 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() { // 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];
        for(int i = 0; i < N - 1; i++) {
            h[i] = height[rank[i]];
        }
    }
    
    char str[MAXN];
    
    inline bool judge(int x, int l1) {
        int i = sa[x];
        int j = sa[x - 1];
        return (i > l1) xor (j > l1);
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("data.in", "r", stdin);
    #endif
        while(scanf("%s%s", s, str) == 2) {
            int l1 = strlen(s);
            s[l1] = '#';
            s[l1 + 1] = 0;
            strcat(s, str);
            N = strlen(s) + 1;
            makesa();
            lcp();
            int ans = 0;
            for(int i = 1; i < N; i++) {
                if(height[i] > ans) {
                    if(judge(i, l1)) {
                        ans = height[i];
                    }
                }
            }
            printf("%d\n", ans);
        }
        return 0;
    }
  • 相关阅读:
    Android开发加快sdk更新速度
    Java 解决约瑟夫问题
    单例模式之我见
    用Java来写常见的排序算法
    一位大牛写的单例
    watchdog监控文件变化使用总结——转载
    python-tkinter使用方法——转载(二)
    python-tkinter使用方法——转载(一)
    python中字符串操作
    python中os模块操作目录与文件名小结
  • 原文地址:https://www.cnblogs.com/moonbay/p/3089567.html
Copyright © 2011-2022 走看看