Suffix automaton request LCS - spoj-LCS

Classic title

Note that the matching time: t-string to s string SAM in the match, and trie as traversal t character, with cur recording length of the current has been matched, if the current character matches the cur ++ (here not directly used cur = len [now]), and vice versa for a mismatch with the link pointer until the match cur = len [now]

Not directly cur = len [now] Why the match is successful? Because the machine is automatically transferred on a plus character in the back, but is not guaranteed without leading character, because len each node is represented by the node maxlen

However, the mismatch can be successfully transferred before cur = len [now], since the shortest run length represented by the node mismatch has len [now] +1, i.e. to the state, then the string must be t minlen [now] the length, maxlen its link points to a state [now] = minlen [now-1] satisfying the condition must be!

#include<bits/stdc++.h>
using namespace std;
#define maxn 250005
struct SAM{
    int cnt,last;
    int nxt[maxn<<1][26];
    int link[maxn<<1];
    int len[maxn<<1];
    SAM(){
        cnt=last=1;
    }
    void insert(int c){
        int p=last,np=last=++cnt;
        len[np]=len[p]+1;
        
        for(;p&&!nxt[p][c];p=link[p])
            nxt[p][c]=np;
        if(!p){link[np]=1;return;}
        
        int q=nxt[p][c];
        if(len[q]==len[p]+1){link[np]=q;return;}
        
        int clone=++cnt;
        link[clone]=link[q];
        len[clone]=len[p]+1;
        memcpy(nxt[clone],nxt[q],sizeof nxt[q]);
        link[q]=link[np]=clone;
        for(;p&&nxt[p][c]==q;p=link[p])
            nxt[p][c]=clone;
    }
    int query(char *s){
        int now=1,Len=strlen(s),cur=0,Max=0;
        for(int i=0;i<Len;i++){
            int c=s[i]-'a';
            if(nxt[now][c]){
                now=nxt[now][c];
                cur++;
            }
            else {
                while(now && !nxt[now][c])now=link[now];
                if(now){
                    cur=len[now]+1;
                    now=nxt[now][c];
                }
                else {
                    now=1;
                    cur=0;
                }
            }
            Max=max(Max,cur); 
        }
        return Max;
    }
}p;
char s[maxn],t[maxn];

int main(){
    scanf("%s%s",s,t);
    int len1=strlen(s);
    int len2=strlen(t);
    for(int i=0;i<len1;i++)
        p.insert(s[i]-'a');
    cout<<p.query(t)<<endl;
}

 

Guess you like

Origin www.cnblogs.com/zsben991126/p/11314564.html