zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    在Lufylegend中如何设置bitmap或者sprite的缩放和旋转中心
    面试必备:文本框与按钮的最简组合
    JavaScript设计模式之策略模式(学习笔记)
    JavaScript设计模式之观察者模式(学习笔记)
    Canvas transform浅析
    JavaScript ArrayBuffer浅析
    IE8-下背景色半透明滤镜在jquery动画中失效问题记录
    JQuery__Tab实践
    memoization提升递归效率
    es6--箭头函数
  • 原文地址:https://www.cnblogs.com/19992147orz/p/7190871.html
Copyright © 2011-2022 走看看