Sam後綴自動機模板

const int maxn = 112345 ,mlen = 26;

struct Sam{
    int len[maxn*2],fa[maxn*2],nex[maxn*2][mlen];
    int _cnt,root,omg;
    int newNode(int L = 0){
        len[_cnt] = L;
        memset(nex[_cnt],fa[_cnt] = -1,sizeof(nex[_cnt]));
        return _cnt++;
    }
    void init(){
        _cnt = 0;
        root = omg = newNode();
    }
    void extend(int x){
        int ox = newNode(len[omg]+1);
        while(omg != -1 && nex[omg][x] == -1){
            nex[omg][x] = ox;
            omg = fa[omg];
        }
        if(omg == -1) fa[ox] = root;
        else{
            int omgx = nex[omg][x];
            if(len[omgx] == len[omg]+1) fa[ox] = omgx;
            else{
                int mgx = newNode(len[omg]+1);
                for(int i=0;i<mlen;i++)
                    nex[mgx][i] = nex[omgx][i];
                fa[mgx] = fa[omgx];
                fa[omgx] = fa[ox] = mgx;
                while(omg != -1 && nex[omg][x] == omgx)
                    nex[omg][x] = mgx,omg = fa[omg];
            }
        }
        omg = ox;
    }
    void build(char *arr){
        init();
        for(int i=0;arr[i];i++){
            extend(arr[i] - 'a');
        }
    }
    void run(char *arr){
        int st = root,lens = 0;
        for(int i = 0;arr[i];i++){
            int x = arr[i] - 'a';
            if(nex[st][x] != -1){
                st = nex[st][x];
                lens++;
            }
            else{
                while(st != -1 && nex[st][x] == -1)
                    st = fa[st];
                if(st == -1){
                    st = root;
                    lens = 0;
                }
                else{
                    lens = len[st]+1;
                    st = nex[st][x];
                }
            }
            //update maxlen
        }
    }
}SAM;


/-------------
const int maxn = 112345,maxLen = 130;

int toid(char c){ return c; }
queue<int> Q;

struct acam{
    int nex[maxn][maxLen],fail[maxn];
    int cnt[maxn];
    int _cnt,root;
    int newNode(){
        memset(nex[_cnt],fail[_cnt] = -1,sizeof(nex[_cnt]));
        cnt[_cnt] = 0;
        return _cnt++;
    }
    void init(){
        _cnt = 0;
        root = newNode();
    }
    void insert(char *arr,int id){
        int st = root;
        for(int i=0;arr[i];i++){
            int & stx = nex[st][toid(arr[i])];
            if(stx == -1) stx = newNode();
            st = stx;
        }
        cnt[st]++;
        // update cnt
    }
    void build(){
        while(Q.empty()==false) Q.pop();
        fail[root] = root;
        int st;
        for(int i=0;i<maxLen;i++){
            if((st = nex[root][i]) != -1){
                fail[st] = root;
                Q.push(st);
            }
            else nex[root][i] = root;
        }
        while(Q.empty()==false){
            st = Q.front(),Q.pop();
            for(int i=0;i<maxLen;i++){
                if(nex[st][i] != -1){
                    int fst = fail[st],son = nex[st][i];
                    while(fst != root && nex[fst][i] == -1)
                        fst = fail[fst];
                    fail[son] = nex[fst][i] == -1 ? root : nex[fst][i];
                    Q.push(son);
                }
                else{
                    nex[st][i] = nex[fail[st]][i];
                }
            }
        };
    }
    int cal(char *arr){
        int st = root;
        for(int i=0;arr[i];i++){
            st = nex[st][toid(arr[i])];
            int tem = st;
            while(tem != root){
                // cal something
                tem = fail[tem];
            }
        }
        // return something
    }
}acam;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章