CF427D

CF427D

SA умна, но бесполезно, ведь доска.

Значение вопросов:

Даны две строки, кратчайшим встретиться общественности происходит только один раз в непрерывной последовательности

Разрешение:

В нормальных условиях, SA используется , чтобы найти самый длинный общий префикс, как если бы публика и самую короткую подстрока задают этот вопрос не имеет ничего общего.
Но мы все еще можем сделать по аналогии идей:

Подумайте о том, почему вы хотите , чтобы найти наибольший элемент ZZ?
Потому что , если меньше , чем максимум, максимальное значение будет включено в этой последовательности.
Таким образом, ответ в том , что один элемент, не значение элемента г не больше , чем это, конечно, выбрать максимальное значение г
из вышеупомянутых идей, найти ответы на то, как получить как малые , как
второй по величине г ценность природы не достаточно, но оказалось , что второе по величине значение + 1 , удовлетворяющее условию
одной стороны, он меньше , чем максимальное значение, максимальное значение однозначно включающее, с другой стороны, он больше , чем второй по величине значения, только максимальное значение содержится
можно разрешить только второй по величине значения +1 а.
Таким образом, в соответствии с описанным выше способом, и вторым по величине максимального значения искания для каждого $ S_1 $ суффикса, вторых по величине значения , а затем обновить ответ ,
и тогда мы можем получить удовольствие с SA решить эту проблему.

КОД:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;

#define LL long long
#define N 10010

string s1,s2,str;
int SA[N],rk[N],tp[N],cnt[N];
int len,tot,m,a[N],height[N];

void qsort() {
    for(int i = 1 ; i <= m ; i++) cnt[i] = 0;
    for(int i = 1 ; i <= tot; i++) cnt[rk[i]]++;
    for(int i = 1 ; i <= m ; i++) cnt[i] += cnt[i - 1];
    for(int i = tot ; i >= 1 ; i--) SA[cnt[rk[tp[i]]]--] = tp[i]; 
}
inline bool cmp(int *f,int x,int y,int w) {
    return f[x] == f[y] && f[x + w] == f[y + w];
}
void build_SA() {
    m = 127;
    for(int i = 1 ; i <= tot ; i++) {
        rk[i] = a[i];
        tp[i] = i;
    }
    qsort();
    for(int w = 1 , p = 0 ; p < tot ; w += w,m = p) {
        p = 0;
        for(int i = tot - w + 1 ; i <= tot ; i++) tp[++p] = i;
        for(int i = 1 ; i <= tot ; i++) {
            if(SA[i] > w) tp[++p] = SA[i] - w;
        } 
        qsort();
        swap(rk,tp);
        rk[SA[1]] = p = 1;
        for(int i = 2 ; i <= tot ; i++) 
            rk[SA[i]] = cmp(tp,SA[i],SA[i - 1],w) ? p : ++p;
    }
    int j = 0, k = 0; 
    for(int i = 1 ; i <= tot ; height[rk[i++]] = k) {
        for(k = k ? k - 1 : k, j = SA[rk[i] - 1] ; a[i + k] == a[j + k] ; k++); 
    }
}
inline bool check(int k,int div) {
    int cnt1 = 0,cnt2 = 0;
    for(int i = 1 ; i <= tot ; i++) {
        if(height[i] < k) {
            if(cnt1 == 1 && cnt2 == 1) return true;
            cnt1 = cnt2 = 0;
            if(SA[i] <= div) cnt1++;
            else if(SA[i] >= div) cnt2++;
            continue;
        }
        if(SA[i] <= div) cnt1++;
        else if(SA[i] >= div) cnt2++;
    }
    return cnt1 == 1 && cnt2 == 1;
}

int main() {
    cin>>s1>>s2;
    len = s1.length();
    str = s1 + '#' + s2;//加入'#'表示两个字符串的分界点。
    tot = len + s2.length() + 1;
    for(int i = 1 ; i <= tot ; i++) a[i] = str[i - 1];
    build_SA();
    int ans = -1;
    for(int i = 1 ; i <= len ; i++) {
        if(check(i,len)) {
            ans = i;
            break;
        }
    }
    printf("%d \n",ans);
    //system("pause");
    return 0;
}

рекомендация

отwww.cnblogs.com/Repulser/p/11373550.html