zoukankan      html  css  js  c++  java
  • bzoj2946

    后缀数组+二分

    中间加个字符,然后二分判断即可

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 100010;
    int n, top, k, tot, m, ans;
    int a[N], sa[N], rank[N], temp[N], lcp[N], belong[N]; 
    bool flag[6];
    char c[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)
    {
        for(int i = 1; i < n; ++i)
        {
            bool ff = true;
            if(lcp[i] >= x)
            {
                flag[belong[sa[i]]] = flag[belong[sa[i + 1]]] = true;
                for(int i = 1; i <= m; ++i) if(!flag[i]) 
                {
                    ff = false;
                    break;
                }
                if(ff) return true;
            }
            else memset(flag, false, sizeof(flag));
        }
        return false;
    }
    int main()
    {
        scanf("%d", &m);
        for(int i = 1; i <= m; ++i)
        {
            scanf("%s", c + 1);
            for(int j = 1; j <= strlen(c + 1); ++j)
            {
                s[++n] = c[j];
                belong[n] = i;
            }
            s[++n] = '#' + i;
        }
        Sa();
        Lcp();
        int l = 0, r = 100000;
        while(r - l > 1)
        {
            int mid = (l + r) >> 1;
            if(C(mid)) l = ans = mid;
            else r = mid;
        }
        printf("%d
    ", ans);
        return 0;
    }
    View Code
  • 相关阅读:
    Window下安装Python
    使用Docker构建一个简单的nginx网页镜像
    solr通过界面管理删除索引和重建索引
    solr8.6添加中文分词器
    php使用solr基础代码类
    window下载安装solr及测试
    Eclipse Android 手机开发作业---心随指动
    Eclipse Android 手机开发作业---空中的气球
    python OpenCV 实现图片的医学处理
    python OpenCV 宽度测量
  • 原文地址:https://www.cnblogs.com/19992147orz/p/7190964.html
Copyright © 2011-2022 走看看