zoukankan      html  css  js  c++  java
  • SPOJ PHRASES Relevant Phrases of Annihilation(后缀数组 + 二分)题解

    题意:

    (n)个串,要你求出一个最长子串(A)(A)在每个字串至少都出现(2)次且不覆盖,问(A)最长长度是多少

    思路:

    后缀数组处理完之后,二分这个长度,可以(O(n))验证可行性,注意是“不覆盖”(英文不好看不懂),随便搞一下就好了。

    代码:

    #include<map>
    #include<set>
    #include<queue>
    #include<cmath>
    #include<stack>
    #include<ctime>
    #include<string>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<sstream>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int maxn = 2e5 + 10;
    const int INF = 0x3f3f3f3f;
    const ull seed = 11;
    const int MOD = 1e9 + 7;
    using namespace std;
    
    int str[maxn];
    int t1[maxn], t2[maxn], c[maxn];
    int sa[maxn];
    int rk[maxn];
    int height[maxn];
    bool cmp(int *r, int a, int b, int l){
        return r[a] == r[b] && r[a + l] == r[b + l];
    }
    void da(int *str, int n, int m){
        n++;
        int i, j, p, *x = t1, *y = t2;
        for(i = 0; i < m; i++) c[i] = 0;
        for(i = 0; i < n; i++) c[x[i] = str[i]]++;
        for(i = 1; i < m; i++) c[i] += c[i - 1];
        for(i = n - 1; i >= 0; i--) sa[--c[x[i]]] = i;
        for(j = 1; j <= n; j <<= 1){
            p = 0;
            for(i = n - j; i < n; i++) y[p++] = i;
            for(i = 0; i < n; i++) if(sa[i] >= j) y[p++] = sa[i] - j;
            for(i = 0; i < m; i++) c[i] = 0;
            for(i = 0; i < n; i++) c[x[y[i]]]++;
            for(i = 1; i < m; i++) c[i] += c[i - 1];
            for(i = n - 1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i];
            swap(x, y);
            p = 1; x[sa[0]] = 0;
            for(i = 1; i < n; i++)
                x[sa[i]] = cmp(y, sa[i - 1], sa[i], j)? p - 1 : p++;
            if(p >= n) break;
            m = p;
        }
        int k = 0;
        n--;
        for(i = 0; i <= n; i++) rk[sa[i]] = i;
        for(i = 0; i < n; i++){
            if(k) k--;
            j = sa[rk[i] - 1];
            while(str[i + k] == str[j + k]) k++;
            height[rk[i]] = k;
        }
    }
    char s[maxn];
    int belong[maxn];
    int num[15], pre[15];
    int tot;
    bool judge(int n){
        for(int i = 1; i <= n; i++){
            if(num[i] < 2) return false;
        }
        return true;
    }
    bool check(int len, int cnt, int n){
        memset(num, 0, sizeof(num));
        memset(pre, -1, sizeof(pre));
        for(int i = 2; i <= cnt; i++){
            if(height[i] >= len){
                if(pre[belong[sa[i - 1]]] == -1){
                    num[belong[sa[i - 1]]]++;
                    pre[belong[sa[i - 1]]] = sa[i - 1];
                }
                else if(abs(pre[belong[sa[i - 1]]] - sa[i - 1]) >= len){
                    num[belong[sa[i - 1]]]++;
                }
                if(pre[belong[sa[i]]] == -1){
                    num[belong[sa[i]]]++;
                    pre[belong[sa[i]]] = sa[i];
                }
                else if(abs(pre[belong[sa[i]]] - sa[i]) >= len){
                    num[belong[sa[i]]]++;
                }
            }
            else{
                if(judge(n)) return true;
                memset(num, 0, sizeof(num));
                memset(pre, -1, sizeof(pre));
            }
        }
        return judge(n);
    }
    int main(){
        int n;
        int T;
        scanf("%d", &T);
        while(T--){
            scanf("%d", &n);
            int cnt = 0;
            for(int i = 1; i <= n; i++){
                scanf("%s", s);
                int len = strlen(s);
                for(int j = 0; j < len; j++){
                    belong[cnt] = i;
                    str[cnt++] = s[j];
                }
                belong[cnt] = -i;
                str[cnt++] = i;
            }
            cnt--;
            str[cnt] = 0;
            da(str, cnt, 130);
    
            int l = 1, r = 10000;
            int Max = 0;
            while(l <= r){
                int m = (l + r) >> 1;
                if(check(m, cnt, n)){
                    Max = m;
                    l = m + 1;
                }
                else{
                    r = m - 1;
                }
            }
            printf("%d
    ", Max);
        }
        return 0;
    }
    
    
  • 相关阅读:
    Spring MVC Ajax 嵌套表单数据的提交
    Spring MVC 过滤静态资源访问
    Spring MVC 页面跳转时传递参数
    IDEA Maven 三层架构 2、运行 springMVC
    IDEA Maven 三层架构 1、基本的Archetype 搭建
    EasyUI DataGrid 基于 Ajax 自定义取值(loadData)
    Spring MVC Ajax 复杂参数的批量传递
    Mybatis Sql片段的应用
    在 Tomcat 8 部署多端口项目
    自动升级的设计思路与实现
  • 原文地址:https://www.cnblogs.com/KirinSB/p/11273136.html
Copyright © 2011-2022 走看看