Word (word)

[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 }

 

Guess you like

Origin www.cnblogs.com/000226wrp/p/11347856.html