zoukankan      html  css  js  c++  java
  • SPOJ

    K - Relevant Phrases of Annihilation

    题目大意:给你 n 个串,问你最长的在每个字符串中出现两次且不重叠的子串的长度。

    思路:二分长度,然后将height分块,看是否存在一个块里面 每个串都符合条件。

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define pii pair<int, int>
    #define y1 skldjfskldjg
    #define y2 skldfjsklejg
    
    using namespace std;
    
    const int N = 1e5 + 7;
    const int M = 1e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    
    char s[N], str[N];
    int n, m, b[N];
    int sa[N], t[N], t2[N], c[N], rk[N], height[N];
    int L[11], R[11];
    
    void buildSa(char *s, int n, int m) {
        int i, j = 0, k = 0, *x = t, *y = t2;
        for(i = 0; i < m; i++) c[i] = 0;
        for(i = 0; i < n; i++) c[x[i] = s[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(int k = 1; k <= n; k <<= 1) {
            int p = 0;
            for(i = n - k; i < n; i++) y[p++] = i;
            for(i = 0; i < n; i++) if(sa[i] >= k) y[p++] = sa[i] - k;
            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(int i = 1; i < n; i++) {
                if(y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k])
                    x[sa[i]] = p - 1;
                else x[sa[i]] = p++;
            }
            if(p >= n) break;
            m = p;
         }
    
         for(i = 1; i < n; i++) rk[sa[i]] = i;
         for(i = 0; i < n - 1; i++) {
            if(k) k--;
            j = sa[rk[i] - 1];
            while(s[i + k] == s[j + k]) k++;
            height[rk[i]] = k;
         }
    }
    
    bool check(int len, int n) {
        int l = 1, r;
        while(l <= n) {
            for(int i = 1; i <= m; i++) L[i] = inf, R[i] = -inf;
            r = l;
            L[b[sa[l]]] = min(L[b[sa[l]]], sa[l]);
            R[b[sa[l]]] = max(R[b[sa[l]]], sa[l]);
            while(r < n && height[r + 1] >= len) {
                r++;
                L[b[sa[r]]] = min(L[b[sa[r]]], sa[r]);
                R[b[sa[r]]] = max(R[b[sa[r]]], sa[r]);
            }
    
            bool flag = true;
    
            for(int i = 1; i <= m; i++) {
                if(L[i] + len > R[i]) {
                    flag = false;
                    break;
                }
            }
    
            if(flag) return true;
            l = r + 1;
        }
        return false;
    }
    
    int main() {
        int T; scanf("%d", &T);
        while(T--) {
            scanf("%d", &m);
    
            char ch = 'A'; int tot = 0;
            for(int i = 1; i <= m; i++) {
                scanf("%s", str);
                int len = strlen(str);
                for(int j = 0; j < len; j++) {
                    s[tot] = str[j];
                    b[tot++] = i;
                }
                s[tot++] = ch++;
            }
            s[tot] = '';
    
            buildSa(s, tot + 1, 180);
    
            int l = 1, r = tot, mid, ans = 0;
    
            while(l <= r) {
                mid = l + r >> 1;
                if(check(mid, tot)) ans = mid, l = mid + 1;
                else r = mid - 1;
            }
    
            printf("%d
    ", ans);
        }
        return 0;
    }
    
    
    /*
    1
    4
    abbabba
    dabddkababa
    bacaba
    baba
    */
  • 相关阅读:
    最全QQ空间说说伪装代码
    Office文件找回技巧
    CentOS7安装CMake(arm版)华为云服务器
    centos7修改ssh端口
    CentOS7安装zookeeper(ARM)版——华为服务器
    CentOS7安装JDK1.8
    Centos7安装Docker
    Prometheus+mysqld_exporter
    Prometheus+blackbox_exporter
    Prometheus+node_exporter
  • 原文地址:https://www.cnblogs.com/CJLHY/p/9343884.html
Copyright © 2011-2022 走看看