• 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
    ", ans + 1); 
        }
        return 0;
    }
    View Code
  • 相关阅读:
    3. What’s New in Spring Security 4.2 spring security 4.2的新功能
    2. Introduction介绍
    1. Getting Started入门
    32. CAS Authentication
    Java序列化
    hive优化--数据倾斜优化
    hive优化之——控制hive任务中的map数和reduce数
    maven中引入jstl
    redis位操作
    Windows单机安装hadoop
  • 原文地址:https://www.cnblogs.com/19992147orz/p/7190871.html
Copyright © 2020-2023  润新知