码迷,mamicode.com
首页 > 编程语言 > 详细

hihocoder1415 后缀数组三·重复旋律3

时间:2017-07-18 10:10:50      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:getheight   sig   inline   gif   out   scanf   style   pac   eth   

传送门: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\n", 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

 

hihocoder1415 后缀数组三·重复旋律3

标签:getheight   sig   inline   gif   out   scanf   style   pac   eth   

原文地址:http://www.cnblogs.com/galaxies/p/hihocoder1415.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!