問題の意味:N * Mとテンプレート行列のX * Yの行列を考えると、マトリックス内のテンプレート行列の出現数を見つけます。
アイデア:
二Weiha西。
接頭語および類似を求めて、ベースはBASE1の長手方向を想定している、横塩基がBASE2あります。
前処理:
ハッシュ[I] [J] =(S [I] [J] - '+ 1)
+ハッシュ[I-1]〜[J] * BASE1
+ハッシュ[I] [J-1] * BASE2
-hash [I-1]〜[J-1] * BASE1 * BASE2
basex = BASE1 ^ xを
basey = BASE2 ^ Y
右下隅[I、J]、ハッシュ値X * Yの領域のサイズ:
ハッシュ[I] [J]
-hash [IX] [J] * basex
-hash [i]は[JY] * basey
+ハッシュ[IX] [JY] * basex * basey
ACコード:
1の#include <iostreamの> 2の#include < ストリング > 3 使用して 名前空間STDを、 4符号なしのtypedef 長い 長ULL。 5 6 CONST ULL BASE1 = 107、BASE2 = 131 。 7 8 文字 S1 [ 1000年 + 10 ] [ 1000年 + 10 ]、S2 [ 100 + 10 ] [ 100 + 10 ]。 9 ULL HASH1 [ 1000年 + 10 ] [1000年 + 10 ]、HASH2 [ 100 + 10 ] [ 100 + 10 ]。 10 ULL basex、basey。 11 整数N、M、X、Y。 12 13 のint main()の 14 { 15 のint T; scanf関数(" %のD "、&T)。 16 一方(T-- ){ 17 のscanf(" %D%D "、&N、&M)。 18 のために(INT iが= 1 ; iが<= N; I ++)のscanf(" %sの"S1 [i]が+ 1 ); 19 20 のscanf(" %D%D "およびX&Y); 21 用(INTは私= 1 ; I <= X; I ++)のscanf(" %sの」、S2 [I] + 1 ); 22 23 のために(INTは私= 1 ; I <= N; I ++ ) 24 のための(INT J = 1 ; J <= Mであり、j ++ ) 25 HASH1 [I] [J] =(S1 [ I] [J] - ' ' + 1)+ HASH1 [I-1 ] [J] * BASE1 + HASH1 [I]、[J- 1 ] * BASE2-HASH1 [I- 1 ] [J- 1 ] * BASE1 * BASE2。 26 27 のために(INT iが= 1 ; iが<= X; I ++ ) 28 のための(INT J = 1 ; J <= Y; J ++ ) 29 HASH2 [I] [J] =(S2 [i]は[J] - [ ' + 1)+ HASH2 [I- 1 ] [j] * BASE1 + HASH2 [I]、[J- 1 ] * BASE2-HASH2 [I- 1 ] [J- 1 ] * BASE1 * BASE2。 30 31 basex = 1、basey = 1 。 32 のために(INT iは= 1 ; iが<= X; I ++)basex = basex * BASE1。 33 のために(INT iは= 1 ; I <= Y; I ++)basey = basey * BASE2。 34 35 INT ANS = 0 。 36 のために(INT I = X; I <= N; I ++ ) 37 のための(INT J = yであり、j <= Mであり、j ++ ) 38 であれば(HASH2 [X] [Y] == HASH1 [I] [J] - HASH1 [IX] [J] * basex-HASH1 [I] [JY] * basey + HASH1 [IX] [JY] * basex * basey) 39 ANS ++ ; 40 41 のprintf(" %dの\ n " 、ANS)。 42 } 43 リターン 0 。 44 }