トピックへのリンク:https://www.luogu.org/problem/P3375
裸KMPで、やがて、それがすべてでは難しいことではありません長い時間、初見のKMPは、日を探していることは理解していなかった、あるいは衝動的な増加率が低すぎる、実際にはよく見てKMPことを覚えておいてください
テンプレートのコードは、それを生きます。
#include <ビット/ STDC ++ H.> 使用して 名前空間STD; のconst int型 MAXN = 1E6 + 10 ; CONST INT INF = 0x3f3f3f3f ; typedefの長い ロングLL; の#define meminf(A)のmemset(A、は0x3F、はsizeof(A)) の#define MEM0(A)のmemset(0、はsizeof(a)参照); CHAR S1 [MAXN]、S2 [MAXN]; int型 ; NXT [MAXN] // ミスマッチモードを記録した後に使用のi番目のビット列に一致していますジャンプモード列に、位置 INT メイン(){ scanfの(" %のSの%S "、S1 + 1、S2 + 1 ); //scanf関数( "%S"、S2 + 1); INT LEN1 = STRLEN(S1の+ 。1)、LEN2の=のSTRLEN(S2は+ 1 ); // 次にNXT配列を求めて、NXTアレイは、パターン文字列自体によって決定 NXT [ 0 ] = 0は、NXTの[ 。1 ] = 0 ; // 第一、第二のミスマッチ、新規の開始にできるだけだけ最初の INT K = 0 ; // ポインタjの次の移動にKポイント位置 // COUT 233 << << ENDLは、 のために(int型 I = 2 ; I <= LEN2; I ++は){ // これで開始パターンマッチング文字列から2番目のビット しばらく(S2 [I] = S2 [! + K 1 ] && K!= 0)= KNXT [K]; IF(S2 [I] == S2 [K + 1 ])NXT [I] = ++ K; } K = 0 ; のための(INT I = 1 ; I <= LEN1; I ++は){ 一方( !K && S1 [I] = S2 [K用+ 1 ])K = NXT [K]; // そうでない場合には、NXTアレイの使用は、バックジャンプ IF(S1 [I] S2 == [K +は1。)K ++]; // それらが等しい場合は、次のいずれかが一致している IF(K == LEN2)のprintf(" %Dの\のn-は"、I-LEN2は+ 1 ); // これらが等しい場合、我々は位置出力を開始 } ため(INT I =1 ; I <LEN2; I ++)のprintf(" %dの" 、NXT [I])。 printf(" %d個の\ n " 、NXT [LEN2])。 リターン 0 ; }