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;
}

 

posted @ 2013-05-20 21:25  moonbay  阅读(181)  评论(0编辑  收藏  举报