zoukankan      html  css  js  c++  java
  • hihocoder1415 后缀数组三·重复旋律3

    传送门:http://hihocoder.com/problemset/problem/1415

    【题解】

    考虑求出两串合在一起(中间加分隔符)后缀数组,就是要求任意在两个串中的$i, j$,$min{h_k} (i leq k leq j)$的最大值。

    考虑$i, j$一定是满足$|i - j| = 1$且合法的时候最优。

    详情见:hihocoder“解题方法提示”

    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 5e5 + 10;
    const int mod = 1e9+7;
    
    # define rank RANK
    
    int n, ans;
    char ch[M];
    int sa[M], rank[M], h[M], t[M];
    int tsa[M], cntA[M], cntB[M], A[M], B[M];
    
    inline void    getsa() {
        fill(cntA, cntA + n + 1, 0);
        for (int i=1; i<=n; ++i) cntA[ch[i]] ++;
        for (int i=1; i<=n; ++i) cntA[i] += cntA[i-1];
        for (int i=n; i; --i) sa[cntA[ch[i]] --] = i;
        rank[sa[1]] = 1;
        for (int i=2; i<=n; ++i) {
            rank[sa[i]] = rank[sa[i-1]];
            if(ch[sa[i-1]] != ch[sa[i]]) ++rank[sa[i]];
        }
        for (int len=1; rank[sa[n]] < n; len <<= 1) {
            fill(cntA, cntA + n + 1, 0);
            fill(cntB, cntB + n + 1, 0);
            for (int i=1; i<=n; ++i) {
                cntA[A[i] = rank[i]] ++;
                cntB[B[i] = ((i+len<=n) ? rank[i+len] : 0)] ++;
            }
            for (int i=1; i<=n; ++i) cntA[i] += cntA[i-1], cntB[i] += cntB[i-1];
            for (int i=n; i; --i) tsa[cntB[B[i]] --] = i;
            for (int i=n; i; --i) sa[cntA[A[tsa[i]]] --] = tsa[i];
            rank[sa[1]] = 1;
            for (int i=2; i<=n; ++i) {
                rank[sa[i]] = rank[sa[i-1]];
                if(A[sa[i]] != A[sa[i-1]] || B[sa[i]] != B[sa[i-1]]) ++rank[sa[i]];
            }
        }
    }
            
    inline void getheight() {
        for (int i=1, j=0; i<=n; ++i) {
            if(j) --j;
            while(ch[i+j] == ch[sa[rank[i]-1] + j]) ++j;
            h[rank[i]] = j;
        }
    }
    
    
    int main() {
        scanf("%s", ch+1);
        n = strlen(ch+1);
        int c = n;
        ch[n+1] = '$';
        scanf("%s", ch+n+2);
        n = strlen(ch+1);
    //    printf("%s
    ", ch+1);
        getsa(); getheight();
        for (int i=2; i<=n; ++i) {
            int pre, suf;
            pre = sa[i-1], suf = sa[i];
            if(pre > suf) swap(pre, suf);
            if(pre <= c && suf > c) ans = max(ans, h[i]);
        }
        cout << ans;
        return 0;
    }
    View Code
  • 相关阅读:
    4-6 R语言函数 排序
    微信公众平台开发接口之天气预报字符串截取
    微信公众平台开发接口之百度翻译
    手机模板 好
    模板1
    手机模板2
    手机模板1
    淘宝素材装修
    如何批量删除SQL注释?
    (3.14)mysql基础深入——mysql 日志分析工具之pt-querty-digest【待完善】
  • 原文地址:https://www.cnblogs.com/galaxies/p/hihocoder1415.html
Copyright © 2011-2022 走看看