后缀数组第一发---在线文本查询

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;
#define N 100000 + 10

char s[N];
int sa[N], t[N], t2[N], c[N], n;

void build_sa(int m)
{
    int i, *x = t, *y = t2;
    for( i = 0; i < m; i++ ) c[i] = 0;
    for( i = 0; i < n; i++ ) c[x[i] = s[i]]++;
    for( i = 1; i < m; i++ ) c[i] += c[i - 1];
    for( i = n - 1; i >= 0; i-- )sa[--c[x[i]]] = i;
    for( int k = 1; k <= n; k <<= 1 ){
        int p = 0;
        for( i = n - k; i < n; i++ ) y[p++] = i;
        for( i = 0; i < n; i++ ) if( sa[i] >= k ) y[p++] = sa[i] - k;
        for( i = 0; i < m; i++ ) c[i] = 0;
        for( i = 0; i < n; i++ ) c[x[y[i]]]++;
        for( i = 0; i < m; i++ ) c[i] += c[i - 1];
        for( i = n - 1; i >= 0; i-- ) sa[--c[x[y[i]]]] = y[i];
        swap(x, y);
        p = 1;
        x[sa[0]] = 0;
        for( i = 1; i < n; i++ )
            x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k] ? p - 1 : p++;
        if( p >= n ) break;
        m = p;
    }
}

int m;
int cmp_suffix(char *str, int num)
{
    return strncmp(str, s + num, m);
}

int Find(char *str)
{
    m = strlen(str);
    if(cmp_suffix(str, sa[0]) < 0) return -1;
    if(cmp_suffix(str, sa[n - 1]) > 0 ) return -1;
    int L = -1, R = n;
    while(L + 1 < R)
    {
        printf("%d--%d\n", L, R);
        int mid = (L + R) >> 1;
        if(cmp_suffix(str, sa[mid]) < 0) R = mid;
        else if(cmp_suffix(str, sa[mid]) > 0) L = mid;
        else return sa[mid];
    }
    return -1;
}

#define M 1000 + 10
char str[M];

int main()
{
    while(~scanf("%s", s))
    {
        n = strlen(s);
        build_sa(128);
        for(int i = 0; i <= n; i++)
            cout << sa[i] << " ";
        cout << endl;

        int q, ans;
        scanf("%d", &q);
        while(q--)
        {
            scanf("%s", str);
            Find(str);
            if((ans = Find(str)) < 0)
                printf("none\n");
            else printf("Find\n");
        }
    }
    return 0;
}

/*


abcabcabc
10



*/

你可能感兴趣的:(ACM)