CF427D

CF427D

SA's clever but useless, in fact the board.

Meaning of the questions:

Given two strings, the shortest meet the public occurs only once in the continuous string

Resolution:

Under normal circumstances, SA are used to find the longest common prefix, as if the public and the shortest substring ask this question has nothing to do.
But we can still draw by analogy ideas:

Think about why you want to find the largest element zz?
Because if less than the maximum, the maximum value will be included in this sequence.
So the answer is that one element, no element z value is greater than this, of course, it is to choose the maximum value of z
from the above ideas, find answers to how to get as small as
the second largest z value of nature is not enough, but found the second largest value + 1 satisfying the condition of
one hand, it is smaller than the maximum value, the maximum value is uniquely comprising; on the other hand, it is larger than the second largest value, only the maximum value is contained
it is possible to permit only the second largest value of +1 of.
Therefore, according to the above method, and the second largest seeking maximum value for every $ S_1 $ suffix, the second largest value and then update the answer
and then we can have fun with SA solve this problem.

CODE:

#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;
}

Guess you like

Origin www.cnblogs.com/Repulser/p/11373550.html