[Problem Description]
Given a particular sequence, this sequence consisting of several words, we now know that a sequence of encryption, known plus
dense sequence must be part of a specific sequence, first find out the encryption sequence in a particular sequence location occurrences.
Note: The encrypted form is replaced, that is, encryption sequence with a specific sequence of words must correspond.
[Input format
of the first row comprises a plurality of words, words to end junction for $, separated by a space between each word, represents a particular sequence, $ is not
counted as a word.
The same format of the second row, indicates encryption sequence.
Note: The number of letters in each sequence of no more than 10 ^ 6,
[Output Format]
position of the first word of the encrypted output sequence occurs in a specific sequence, to ensure that the answer must exist.
[O] Sample
input
aaabcdabc $
XY $
output
3
input
abcxczzabc $
Prvi Prvi TR TR DR X $
output
3
output
3
input
XYZ XYZ $ ABC ABC
ABC ABC $
output
2
[DESCRIPTION] Data
for 50% of the data, N≤1000.
To 100% of the data, 2≤N≤300000.
Ideas:
This problem is to let us in a long string to find a similar sub-structure, we found that, although the character is not the same, but in the same string with a distance of one character interval should be the same, then we use the distance to construct match string
In the following example:
a b c x c z z a b c $
prvi dr prvi tr tr x $
String is generated:
0 0 0 0 2 0 1 7 7 5
0 0 2 0 1 0
Then we will find:
0 0 2 0 1 7
with
0 0 2 0 1 0
Match up? ? ?
That's because the main impact of the value before the string value may be the main string
Then there is obviously of the following two points
1. The main string values in the first time in this match, if match, the bit string 2 0
2. Because it is the first time, the distance represented by the bit sequence number 1 should exceed this matching string length
So have:
while(j&&(s1[i+1]!=s2[j+1]&&(s2[j+1]>0||j-s1[i+1]>=0))) j=kmp[j];
if(s1[i+1]==s2[j+1]||(s2[j+1]<=0&&j-s1[i+1]<0)) j++;
Then the code can be more than
1 #include <cstdio> 2 #include <cstring> 3 4 using namespace std; 5 6 #define GC getchar() 7 #define R register 8 #define MAXN 1000000+5 9 #define mod1 838379 10 #define mod2 13578987531 11 #define ll long long 12 13 int s1[MAXN],s2[MAXN]; 14 int kmp[MAXN],pl[mod1+5]; 15 int cnt1=0,cnt2=0; 16 ll h[mod1+5]; 17 18 inline char clear(); 19 inline void pre(); 20 inline void KMP_pre(); 21 inline void KMP(); 22 23 int main() 24 { 25 pre(); 26 KMP_pre(); 27 KMP(); 28 return 0; 29 } 30 31 inline char clear() 32 { 33 char c=GC; 34 while (c<'a' || c>'z') c=GC; 35 return c; 36 } 37 38 inline void pre() 39 { 40 freopen("word.in","r",stdin); 41 freopen("word.out","w",stdout); 42 R char c=clear(); 43 while(c!='$') 44 { 45 R ll x=0; 46 while(c>='a'&&c<='z') x=(x*37+(c-'a'+1))%mod2,c=GC; 47 R ll tx=x%mod1;cnt1++; 48 while(h[tx]) 49 { 50 if(h[tx]==x) 51 { 52 is S1 [CNT1] = CNT1-PL [TX]; // record length difference 53 is PL [TX] = CNT1; BREAK ; // record this address 54 is } 55 TX = (TX + . 1 )% MOD1; // process Ha Xi conflicts 56 is } 57 is IF (! H [TX]) 58 { 59 S1 [CNT1] = 0 ; 60 H [TX] = X, PL [TX] = CNT1; 61 is } 62 is C = the GC; 63 is } 64 memset(h,0,sizeof(h)); 65 memset(pl,0,sizeof(pl)); 66 c=clear(); 67 while(c!='$') 68 { 69 R ll x=0; 70 while(c>='a'&&c<='z') x=(x*37+(c-'a'+1))%mod2,c=GC; 71 R ll tx=x%mod1;cnt2++; 72 while(h[tx]) 73 { 74 if(h[tx]==x) 75 { 76 s2[cnt2]=cnt2-pl[tx];//同上 77 pl[tx]=cnt2;break; 78 } 79 tx=(tx+1)%mod1; 80 } 81 if(!h[tx]) 82 { 83 s2[cnt2]=0; 84 h[tx]=x,pl[tx]=cnt2; 85 } 86 c=GC; 87 } 88 89 //for(R int i=1;i<=cnt1;i++) printf("%d ",s1[i]); 90 //printf("\n"); 91 //for(R int i=1;i<=cnt2;i++) printf("%d ",s2[i]); 92 //printf("\n"); 93 } 94 95 inline void KMP_pre() 96 { 97 kmp[1]=0; 98 for(R int i=1,j=0;i<cnt2;i++) 99 { 100 while(j&&s2[i+1]!=s2[j+1]) j=kmp[j]; 101 if(s2[i+1]==s2[j+1]) j++; 102 kmp[i+1]=j; 103 } 104 } 105 106 inline void KMP() 107 { 108 for(R int i=0,j=0;i<cnt1;i++) 109 { 110 while(j&&(s1[i+. 1 !] = S2 [J + . 1 ] && (S2 [J + . 1 ]> 0 || J-S1 [I + . 1 ]> = 0 ))) J = KMP [J]; 111 / * main string 1. The times the first occurrence in the current matching, if it matches, this bit string 0 2 112 2. because it is the first time, the distance represented by the number 1 position should go beyond the current string match string length * / 113 IF (S1 [I + . 1 ] == S2 [J + . 1 ] || (S2 [J + . 1 ] <= 0 && J-S1 [I + . 1 ] < 0 )) J ++ ; 114 IF (J == CNT2 ) {the printf ( " % D \ n- " , I + . 1 -cnt2 + . 1 ); return;} 115 } 116 putchar('0'),putchar('\n'); 117 return; 118 }