萌新,编译错误到怀疑人生
查看原帖
萌新,编译错误到怀疑人生
42892
dwbcz楼主2020/7/22 22:06
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define maxc 27   //字符集的大小 a~z
#define maxs 250005 //字符串大小
#define smax 500005 //自动机上的状态数,应该开到两倍的字符串长度
#define mem(a) memset(a,0,sizeof(a))
#define f(c,a,b) for(int c=a; c<=b; c++)

using namespace std;
typedef long long ll;
char a[maxs], b[maxs];
int sl, size, last, sb, ans; //字符串长度,状态数,上一次extend完的那个状态
int to[smax][maxc];  //trans,转移函数
int mal[smax], link[smax]; //一个状态表示的最大长度的串,后缀链接
//一个状态表示的最小长度的串就等于它后缀链接的那个mal-1

void init(){ 
    mem(to); mem(mal); mem(link); 
    last = size = 1; //SAM的开始节点为1
    sl = strlen(a);
    sb = strlen(b);
    ans = 0;
}

void extend(int c){
    int p, cur=++size;
    mal[cur] = mal[last] + 1;
    //情况一,前面的指向都为空
    for(p=last; p&&!to[p][c]; p=link[p]) to[p][c] = cur;
    if(!p) link[cur] = 1;
    else{
        int q = to[p][c]; //到状态q后面不为空
        //情况二A,这个状态的maxlen 正好和当前需要的一致
        if(mal[q] == mal[p] + 1) link[cur] = q;
        else{ //情况二B,需要拆分这个状态
            int cl = ++size; //克隆一个用来装短的部分
            mal[cl] = mal[p] + 1;
            memcpy(to[cl], to[q], sizeof(to[q]));
            link[cl] = link[q];
            while(p && to[p][c] == q){
                to[p][c] = cl;
                p = link[p];
            }
            link[cur] = link[q] = cl;
        }
    }
    last = cur;
}

void lcs(){
    int p=1, nl=0;
    f(i,0,sb-1){
        while( !to[p][b[i]-'a'] && p ) {
            p = link[p];
            nl = mal[p];
        }
        if(p) {
            nl++;
            p = to[p][b[i]-'a'];
            ans = max( ans, nl );
            //cout<<i<<' '<<p<<' '<<mal[p]<<endl;
        }else { p=1; nl=0; }
    }
}

int main(){
    //freopen("owo.in","r",stdin);
    scanf("%s%s", a, b);
    init();
    f(i,0,sl-1) extend(a[i]-'a');
    lcs();
    cout<<ans<<endl;
    return 0;
}

rt。。。为什么呀1551,quq求大佬帮助

2020/7/22 22:06
加载中...