交流オートマトン暴力的なジャンプは--hdu5880に一致しません

非常に簡単な質問、交流自動機別のLENでこのノードが可能ではないですが、失敗する危険があるため、ノードのそれぞれが照会する使用の暴力ホップの中に失敗する必要があり、それぞれの状態を表す長い文字列を維持ノードは、直接的な休憩を見つけます

速いの配列に続いて差分統計カバレッジ

使用して 名前空間はstdを、
#define N 1000005

チャーS [N]、T [N]。
int型N、CNT [N]。

構造体トライ{
     INT NXT [N] [ 26 ]、失敗[N]、エンド[N]、レン[N]。
    int型の根、L。
    int型newnode(){
        memsetの(NXT [L]、 - 1はsizeof NXT [L])。
        端[L] = 0 ;
        リターン L ++ ;
    }
    無効{INITを()
        L = 0 
        ルート = newnode()。
    }
    ボイドインサート(チャーBUF []){
         int型 LEN = STRLEN(BUF)。
        int型になりました= ルート。
        以下のためにint型 i = 0 ; iがLEN <; iは++ ){
             場合(NXT [今] [BUF [I] - ' ' ] == - 1 
                NXT [今] [BUF [I] - [ A ' ] = newnode()。 = NXT [今] [BUF [I] - ' ' ]。
        }
        【今】終了 ++;レン[今] = LEN。
    }
    のビルド(){
        キュー < 整数 > Q;
        【ルート】フェイル = ルートと、
        以下のためにint型 i = 0 ; iは< 26 ; iは++ 場合(NXT [ルート] [I] == - 1 
                NXT [ルート] [I] = 根。
            他の{
                失敗[NXT [ルート] [I] = 根。
                q.push(NXT [ルート] [I])。
            }
        一方、(q.size()){
             int型 = NOW )q.front(。
            q.pop(); 
            以下のためにint型 i = 0 ; iは< 26 ; iは++ 場合(NXT [今] [I] == - 1 
                    NXT [今] [I] = NXT [I] [今] [失敗]。
                他の{
                    失敗[NXT [今] [I] = NXT [I] [今] [失敗]。
                    q.push(NXT [今] [I])。
                }
        }
    }
    
    のクエリ(のchar *のS){
         int型になりました= 根を。
        INT LEN = STRLEN(S)。
        以下のためにint型 i = 0 ; iがLEN <; iは++ ){
             もし、(S [i]が< ' ' || sの[I]> ' Z ' ){ =ルート。続け;
            } = NXT [今] [S [I] - [ A ' ];
             int型 P = 今、
             一方(P){
                 IF(完[P]){ // ノードの危険 
                    CNT [Iは+ 1 ] - ;
                    CNT [I -len [P] + 1 ] ++ ;
                    破ります;
                }
                P = 失敗[P]。
            }
        }
    }
}交流;

INT のmain(){
     int型 TT; CIN >> TT。一方、(tt-- ){
        ac.init();
        cinを >> N;
        以下のためにint型 i = 1 ; iが++; iが<= N ){
            scanf関数(" %sの" 、S);
            ac.insert(S);
        }
        ac.build();
        
        F;
        INT LEN = 0 
        getchar関数();
        scanf関数(" %の[^ \ n]は%※C " 、S);
        LEN = strlenを(S)。
        
        以下のためにint型 i = 0 ; iがLEN <; iは++ ){
            T [I] =のS [i]は、
            もし(S [I]> = ' A ' && S [I] <= ' Z ' 
                S [i]が + = ' ' - ' A ' 
        }
        T [S] = 0 ;
        
        以下のためにint型 i = 0 ; iは= LEN <; iは++)CNTを[I] = 0 ;
        ac.query(S);
        int型 i = 1 ; iがLEN <; I ++)はCNT [I] + = CNT [I- 1 ]。
        以下のためにint型 I = 0 ; iが<LEN; iが++ ){
             場合(CNT [I]> = 1)のprintf(" * " )。
            のprintf(" %のC " 、T [I])。
        }
        
        プット("" );
    }
}

 

おすすめ

転載: www.cnblogs.com/zsben991126/p/11706137.html