P2375 [NOI2014] KMP動物園

まあ、暴力は宇宙qwqの$ \ $ 50ptsを得ることができます


 

暴力のアイデアは、それが文字列の半分以下の長さになるまで、[J] $ $のNXTホッピング保つことで、その後、カウントを開始し、もちろん、その後の$ NXTにジャンプ[J] $

ポジティブ・ソリューションズ:(重複しない必要はありません)必要な長さではありません、共通の接頭辞と接尾辞の数、[i]を=のANS [J] + 1 $が$ Iに対応して明らかに$ ANSを考慮$ $ J $は、私は自分自身を$ $を超えているよりも、 。

したがって、溶液プロセスは、$ NUM中$ KMP $を模倣する[I] $次に、$ jの<= \ FRAC {I} {2} $、$ NUM [I] =のANSまで、[J] $ $のNXTホッピング保つことです[ J] $

なお、ここで模倣$のKMPの$理由は、次の試合のために、$のNXTのいくつかの冗長性をスキップ[J] $($のNXT [J] $が大きすぎる)を避けるためです、$ jの$の最後$ \ FRAC {I}最長共通接頭辞と接尾辞の{2} $の長さに等しい未満の最後の時間、あなたは直接の$ NXTで走り幅跳び[J] $を、一致一致させることができるならば、それ以外の場合は、踊ってきました試合までの$ NXT [J] $、。

#include <cstdioを> 
する#include <iostreamの> 
する#include <アルゴリズム> 
の#include <CStringの> 
する#include <cmath> 
の#include <CCTYPE> 
の#include <cstdlib> 
の#include <ベクトル> 
の#include <キュー> 
の#include <地図> 
#include < 設定 >
 の#define ULL符号なし長い長
 の#defineが長い長いちゃう
 の#define Rレジスタint型
 の#defineのための休止(Rは、i = 1; iが<= 10000000000; ++ I)の
 使用 名前空間STDを、
名前空間FREAD {
     静的 チャーB [ 1 << 15 ]、* S = B * D = B。
    #define GETCHAR()(S == D &&(D =(S = B)+関数fread(B、1,1 << 15、STDIN)、S == D)EOF:* S ++)
    インラインINT G(){ 
        R RET = 0、=解決1登録のchar chのを。しばらく(!isdigit(CH = getchar関数()))修正= CH == ' - ' - ?1 :修正します。
        DO RET = RET * 10 +(CH ^ 48)。一方、(isdigit(CH = GETCHAR()))。リターンのRET *の修正。
    }インラインブールのisEmpty(CONST  チャー&CH){ 戻り CH <= 36 || CH> = 127 ;} 
    インラインボイド GS(チャー *秒){登録チャー CHと、一方(のisEmpty(CH = GETCHAR()))。やる * S ++ = CHを; 一方(のisEmpty(CH =!GETCHAR()));} 
} 使用 FREAD :: Gと、使用FREAD :: GSを。
const  int型 M = 十億七int型 nは、NXT [ 1000010 ]、ANS [ 1000010 ]。チャー S [ 1000010 ]。LL NUM = 1; 
インラインボイド PRE(){NXTは、[ 1 ] = 0 ための(R I = 2、J = 0 ; ++; iが<= N {I) 
         一方、(!J && S [I] = S [J + 1 ])J = NXT [J]。
        もし(S [I] == S [j + 1 ])++ J。NXT [I] = jは、
        ANS [I] =のANS [J] + 1 
    } 
} 
インラインボイドCALC(){
     (R I = 2、J = 0 ; iが<= N ++ {I)
         一方、(J && S [I] = sの[J +!1 ])J =NXT [J]。
        もし(S [I] == S [j + 1 ])++ J。 
        一方、(J> I / 2)J = NXT [J]。
        (NUM * =(ANS [J] + 1))%= M。
    } 
} 
(){主符号付き
の#ifdef JACK 
    freopenは("NOIPAK ++で"" R " 、STDIN)。
#endifの
    R T = G(); (R I = 1 ; I <= T; ++ I){memsetの(S、0はsizeof(S))。NUM = 1 
        GS(S + 1); N = STRLEN(S + 1)。ANS [ 1 ] = 1 PRE();
//         のための(R I = 2; iが<= N; ++ I){R LIM = I / 2、J = I、CNT = 0。
//             一方(J){J = NXT [J]。IF(J && J <= LIM)++ CNT;}
 //             (ANS * =(CNT + 1))%= M。 
//         } 
        CALC()。
        printf(" %LLDする\ n " 、NUM)。
    } 
}

2019年6月15日

 

おすすめ

転載: www.cnblogs.com/Jackpei/p/11028492.html