Longest Repeated Substring zoj3199

来源:互联网 发布:100部网络删除小说rar 编辑:程序博客网 时间:2024/05/24 00:56

比论文上的那题简单,直接由高到低枚举长度,发现重复超过一次的就是答案


#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <queue>#include <algorithm>#include <vector>#include <cstring>#include <stack>#include <cctype>#include <utility>   #include <map>#include <string>  #include <climits> #include <set>#include <string>    #include <sstream>#include <utility>   #include <ctime>using std::priority_queue;using std::vector;using std::swap;using std::stack;using std::sort;using std::max;using std::min;using std::pair;using std::map;using std::string;using std::cin;using std::cout;using std::set;using std::queue;using std::string;using std::istringstream;using std::make_pair;using std::getline;using std::greater;using std::endl;using std::multimap;using std::deque;typedef long long LL;typedef unsigned long long ULL;typedef pair<int, int> PAIR;typedef multimap<int, int> MMAP;const int MAXN(50010);const int SIGMA_SIZE(26);const int MAXM(110);const int MAXE(300010);const int MAXH(18);const int INFI((INT_MAX-1) >> 1);const int MOD(2520);const ULL BASE(31);const ULL LIM(1000000000000000ull);struct SA{    char S[MAXN];    int sa[MAXN], t1[MAXN], t2[MAXN], cnt[MAXN], len, M;    void init(int tl, int tm = 128)    {        len = tl;        M = tm;        int *p1 = t1;        int *p2 = t2;        for(int i = 0; i < M; ++i) cnt[i] = 0;        for(int i = 0; i <= len; ++i) ++cnt[p1[i] = S[i]];        for(int i = 1; i < M; ++i) cnt[i] += cnt[i-1];        for(int i = len; i >= 0; --i) sa[--cnt[p1[i]]] = i;        int temp = 1;        for(int k = 1; temp <= len; k <<= 1)        {            temp = 0;            for(int i = len-k+1; i <= len; ++i) p2[temp++] = i;            for(int i = 0; i <= len; ++i)                if(sa[i] >= k)                    p2[temp++] = sa[i]-k;                        for(int i = 0; i < M; ++i) cnt[i] = 0;            for(int i = 0; i <= len; ++i) ++cnt[p1[p2[i]]];            for(int i = 1; i < M; ++i) cnt[i] += cnt[i-1];            for(int i = len; i >= 0; --i) sa[--cnt[p1[p2[i]]]] = p2[i];            swap(p1, p2);            temp = 1;            p1[sa[0]] = 0;            for(int i = 1; i <= len; ++i)                p1[sa[i]] = p2[sa[i-1]] == p2[sa[i]] && p2[sa[i-1]+k] == p2[sa[i]+k]? temp-1: temp++;            M = temp;        }    }    int rank[MAXN], height[MAXN];    void getHeight()    {        int k = 0;        for(int i = 0; i <= len; ++i)            rank[sa[i]] = i;        for(int i = 0; i < len; ++i)        {            if(k) --k;            int j = sa[rank[i]-1];            while(S[i+k] == S[j+k]) ++k;            height[rank[i]] = k;        }    }    int Log[MAXN];    int table[MAXH][MAXN];    void initLog()    {        Log[0] = -1;        for(int i = 1; i < MAXN; ++i)            Log[i] = (i&(i-1))? Log[i-1]: Log[i-1]+1;    }    void initRMQ()    {        for(int i = 1; i <= len; ++i)            table[0][i] = height[i];        for(int i = 1; (1 << i) <= len; ++i)            for(int j = 1; j+(1 << i)-1 <= len; ++j)                table[i][j] = min(table[i-1][j], table[i-1][j+(1 << (i-1))]);    }    int lcp(int a, int b)    {        a = rank[a];        b = rank[b];        if(a > b) swap(a, b);        ++a;        int temp = Log[b-a+1];        return min(table[temp][a], table[temp][b-(1 << temp)+1]);    }};SA sa;int main(){sa.initLog();int TC;scanf("%d", &TC);while(TC--){scanf("%s", sa.S);int len = strlen(sa.S);sa.init(len);sa.getHeight();sa.initRMQ();int ans = len/2+1;for(; ans >= 1; --ans){bool flag(false);int lim = len-ans;for(int i = 0; i <= lim; i += ans){int temp = sa.lcp(i, i+ans);if(temp >= ans){flag = true;break;}int ti = i-(ans-temp%ans);if(ti >= 0){temp = sa.lcp(ti, ti+ans);if(temp >= ans){flag = true;break;}}}if(flag)break;}printf("%d\n", ans);}return 0;}







原创粉丝点击