poj1743

二分+后缀数组

并查集怎么做?

二分长度,然后扫描一遍,如果lcp比值大,那么肯定能满足这个x,因为lcp比x大说明包含长x的lcp

 

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 40010;
int n, top, k, tot, m;
int a[N], sa[N], rank[N], temp[N], lcp[N], s[N]; 
bool cp(int i, int j)
{
    if(rank[i] != rank[j]) return rank[i] < rank[j];
    int ri = i + k <= n ? rank[i + k] : -1;
    int rj = j + k <= n ? rank[j + k] : -1;
    return ri < rj;
}
void Sa()
{
    for(int i = 1; i <= n; ++i)
    {
        sa[i] = i;
        rank[i] = s[i];
    }
    for(k = 1; k <= n; k <<= 1)
    {
        sort(sa + 1, sa + n + 1, cp);
        temp[sa[1]] = 1;
        for(int i = 2; i <= n; ++i) temp[sa[i]] = temp[sa[i - 1]] + (cp(sa[i - 1], sa[i]));
        for(int i = 1; i <= n; ++i) rank[i] = temp[i];
    }
}
void Lcp()
{
    for(int i = 1; i <= n; ++i) rank[sa[i]] = i;
    int h = 0;
    for(int i = 1; i <= n; ++i)
    {
        int j = sa[rank[i] - 1];
        if(rank[i] <= 1) continue;
        if(h) --h;
        for(; i + h <= n && j + h <= n; ++h) if(s[i + h] != s[j + h]) break;
        lcp[rank[i] - 1] = h;        
    }
}
bool C(int x)
{
    int mn = 1 << 29, mx = 0;
    for(int i = 1; i < n; ++i)
    {
        if(lcp[i] >= x)
        {
            mx = max(mx, max(sa[i], sa[i + 1]));
            mn = min(mn, min(sa[i], sa[i + 1]));
            if(mx - mn > x) return true;
        }
        else
        {
            mn = 1 << 29;
            mx = 0;
        }
    }
    return false;
}
int main()
{
    int T;
    while(scanf("%d", &n))
    {
        if(n == 0) break;        
        for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
        for(int i = 2; i <= n; ++i) s[i - 1] = a[i] - a[i - 1] + 100; 
        --n; 
        Sa();
        Lcp();
        int l = 1, r = 20010, ans = 0;
        while(r - l > 1)
        {
            int mid = (l + r) >> 1;
            if(C(mid)) l = ans = mid;
            else r = mid;
        }
        if(ans < 4) puts("0");
        else printf("%d\n", ans + 1); 
    }
    return 0;
}
View Code

 

posted @ 2017-07-16 16:30  19992147  阅读(106)  评论(0编辑  收藏  举报