рдмрд╣реБрдкрдж рд╣реИрд╢ рдФрд░ рдЙрдирдХреЗ рдЖрд╡реЗрджрди

рд╣реЗрд▓реЛ, рд╣реИрдмрд░ред рдЖрдЬ рдореИрдВ рд▓рд┐рдЦреВрдВрдЧрд╛ рдХрд┐ рдЖрдк рд╡рд┐рднрд┐рдиреНрди рдПрд▓реНрдЧреЛрд░рд┐рдердо рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдкрдж рд╣реИрд╢ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдЗрд╕рдХреЗ рдмрд╛рдж рдмрд╕ рд╣реИрд╢)ред

рдкрд░рд┐рдЪрдп


рдЪрд▓рд┐рдП рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╣реИ 0..n-1 ред рдЗрд╕ рд░реЗрдЦрд╛ рдХрд╛ рдмрд╣реБрдкрдж рд╣реИрд╢ рд╕рдВрдЦреНрдпрд╛ h = рд╣реИрд╢ (sред 0.n-1 ) = s 0 + ps 1 + p 2 s 2 + ... + p n-1 s n-1 рд╣реИ , рдЬрд╣рд╛рдБ p рдХреБрдЫ рдкреНрд░рд╛рдХреГрддрд┐рдХ рд╕рдВрдЦреНрдпрд╛ рд╣реИ (рдмрд╛рдж рдореЗрдВ рдпрд╣ рд╣реЛрдЧрд╛) рдпрд╣ рдХрд╣рд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдХреМрди рд╕рд╛ рд╣реИ), рдФрд░ рдореИрдВ i рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ i-рд╡реЗрдВ рдЪрд░рд┐рддреНрд░ рдХрд╛ рдХреЛрдб рд╣реИ (рд▓рдЧрднрдЧ рд╕рднреА рдЖрдзреБрдирд┐рдХ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдЗрд╕реЗ s[i] рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ)ред

рд╣реИрд╢ рдХреА рд╕рдВрдкрддреНрддрд┐ рд╣реИ рдХрд┐ рдПрдХ рд╣реА рддрд╛рд░ рдХреА рд╣реИрд╢ рдЬрд░реВрд░реА рд╕рдорд╛рди рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рдореБрдЦреНрдп рдСрдкрд░реЗрд╢рди рдЬреЛ рд╣реИрд╢ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рд╕рдорд╛рдирддрд╛ рдХреЗ рд▓рд┐рдП рджреЛ рдкрджрд╛рд░реНрдереЛрдВ рдХреА рддреНрд╡рд░рд┐рдд рддреБрд▓рдирд╛ рд╣реИред рдмреЗрд╢рдХ, 2 рд▓рд╛рдЗрдиреЛрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рд╕рдорд╛рди рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ (рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд▓рд╛рдЗрдиреЛрдВ рдХреА рд▓рдВрдмрд╛рдИ s рдФрд░ t рд╕рдВрдпреЛрдЧ рд╣реИ рдФрд░ n рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ):

 boolean equals(char[] s, char[] t) { for (int i = 0; i < n; i++) if (s[i] != t[i]) { return false; } } return true; } 

рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╕рдмрд╕реЗ рдЦрд░рд╛рдм рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╕рднреА рд╡рд░реНрдгреЛрдВ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП, рдЬреЛ рдУ (рдПрди) рдХреЗ рд╕реНрдкрд░реНрд╢реЛрдиреНрдореБрдЦ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рджреЗрддрд╛ рд╣реИред

рд╣реИрд╢ рдХреЗ рд╕рд╛рде рддрд╛рд░ рдХреА рддреБрд▓рдирд╛ рдХрд░реЗрдВ


рдЕрдм рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рд╣реИрд╢ рдРрд╕рд╛ рдХреИрд╕реЗ рдХрд░рддрд╛ рд╣реИред рдЪреВрдВрдХрд┐ рдПрдХ рд╣реИрд╢ рд╕рд┐рд░реНрдл рдПрдХ рд╕рдВрдЦреНрдпрд╛ рд╣реИ, рд╣рдореЗрдВ рдЙрдирдХреА рддреБрд▓рдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП O (1) рд╕рдордп рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╕рдЪ рд╣реИ, рдПрдХ рднреЛрд▓реЗ рддрд░реАрдХреЗ рд╕реЗ рдПрдХ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдХреЗ рд╣реИрд╢ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдУ (рдПрди) рд╕рдордп рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЗрд╕рд▓рд┐рдП, рдЖрдкрдХреЛ рдЧрдгрд┐рддреАрдп рд╕реВрддреНрд░реЛрдВ рдХреЗ рд╕рд╛рде рдереЛрдбрд╝рд╛ рдЫреЗрдбрд╝рдЫрд╛рдбрд╝ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдФрд░ рдУ (рдПрди) рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╛рд░ рдореЗрдВ рд╕рднреА рд╕рдмрд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд╣реИрд╢ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рд╕реАрдЦрдирд╛ рд╣реЛрдЧрд╛ред рдЪрд▓реЛ рд╕рдмреНрд╕рдЯреНрд░реЗрдЯ рдХреЗ рдПрд▓..рдЖрд░ рдФрд░ рдЯреА рдПрдХреНрд╕..рд╡рд╛рдИ (рдПрдХ рд╣реА рд▓рдВрдмрд╛рдИ рдХреЗ) рдХреА рддреБрд▓рдирд╛ рдХрд░реЗрдВред рд╣реИрд╢ рдкрд░рд┐рднрд╛рд╖рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рд╣рдо рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ:

s L + ps L + 1 + ... + p RL-1 s R-1 + p RL s R = t X + pt X + 1 + ... + p YX-1 t Y-1 + p YX t Y

рд╣рдо рдмрд╛рдИрдВ рдУрд░ рдЫреЛрдЯреЗ рдкрд░рд┐рд╡рд░реНрддрди рдХрд░реЗрдВрдЧреЗ (рджрд╛рдИрдВ рдУрд░ рд╕рдм рдХреБрдЫ рдЗрд╕реА рддрд░рд╣ рд╣реЛрдЧрд╛)ред рд╣рдо рд╕рдмрд░рд┐рдВрдЧ рдХреЗ рд╣реИрд╢ рд▓рд┐рдЦрддреЗ рд╣реИрдВред 0. , рд╣рдореЗрдВ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

рд╣реИрд╢ (s 0..R ) = s 0 + ps 1 + ... + p L-1 s L-1 + p L s L + p L + 1 s L + 1 + ... + p R-1 s R-1 + рдкреА рдЖрд░ рдПрд╕ рдЖрд░

рд╣рдо рдЗрд╕ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЛ рджреЛ рднрд╛рдЧреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░реЗрдВрдЧреЗ ...

рд╣реИрд╢ (s 0..R ) = (s 0 + ps 1 + ... + p L-1 s L-1 ) + (p L L L + p L + 1 s L + 1 + ... + p R-1 s R-1 + p R s R )

... рдФрд░ рдХрд╛рд░рдХ рдмреНрд░реИрдХреЗрдЯ рдХреЛ рджреВрд╕рд░реА рдмреНрд░реИрдХреЗрдЯ рд╕реЗ рдирд┐рдХрд╛рд▓реЗрдВ:

рд╣реИрд╢ (s 0..R ) = (s 0 + ps 1 + ... + p L-1 s L-1 ) + p L (s L + ps L + 1 + ... + p RL-1 s R-1 + рдкреА рдЖрд░рдПрд▓ рдПрд╕ рдЖрд░ )

рдкрд╣рд▓реЗ рдмреНрд░реИрдХреЗрдЯ рдореЗрдВ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╕рдмреНрд░рд┐рдВрдЧ s 0..L-1 рдХрд╛ рд╣реИрд╢ рд╣реИ, рдФрд░ рджреВрд╕рд░реЗ рдореЗрдВ, рд╕рдмрд╕реНрдЯреНрд░рд┐рдВрдЧ s L..R рдХреА рд╣реИрд╢ рдХреА рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ ред рддреЛ, рд╣рдореЗрдВ рдпрд╣ рдорд┐рд▓рд╛:

рд╣реИрд╢ (рдПрд╕ред 0. рдЖрд░ ) = рд╣реИрд╢ (рдПрд╕ 0. рдПрд▓ -1 ) + рдкреА рдПрд▓ рд╣реИрд╢ ( рдПрд▓ рдПрд▓ рдЖрд░ )

рдЗрд╕рдХрд╛ рддрд╛рддреНрдкрд░реНрдп рд╣реИрд╢ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрди рд╕реВрддреНрд░ рд╕реЗ рд╣реИ ( рдПрд▓ LR ) :

рд╣реИрд╢ (s L..R ) = (1 / p L ) (рд╣реИрд╢ (s 0..R ) - рд╣реИрд╢ ( 0.L-1 ))

рдЗрд╕реА рдкреНрд░рдХрд╛рд░, рд╣рдорд╛рд░реЗ рджреВрд╕рд░реЗ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд▓рд┐рдП рд╕рдорд╛рдирддрд╛ рд╣реИрд╢ (t X..Y ) = (1 / p X ) (рд╣реИрд╢ (t 0..Y ) - рд╣реИрд╢ (t 0..X-1 )) рд╕рдВрддреБрд╖реНрдЯ рд╣реЛ рдЬрд╛рдПрдЧреАред

рдЗрди рдлрд╝рд╛рд░реНрдореБрд▓реЛрдВ рдХреЛ рдзреНрдпрд╛рди рд╕реЗ рджреЗрдЦрдиреЗ рдкрд░, рд╣рдо рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХрд┐рд╕реА рднреА рд╡рд┐рдХрд▓реНрдк рдХреЗ рд╣реИрд╢ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЗрд╕ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рдЙрдкрд╕рд░реНрдЧреЛрдВ рдХреЗ рдХреЗрд╡рд▓ 0..0 , s 0..1 , ..., s 0..n-2 , s 0 рдХреЛ рдЬрд╛рдирдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ ред .n-1 ред рдФрд░, рдЪреВрдВрдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдмрд╛рдж рдХреЗ рдЙрдкрд╕рд░реНрдЧ рдХрд╛ рд╣реИрд╢ рдкрд┐рдЫрд▓реЗ рдПрдХ рдХреЗ рд╣реИрд╢ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╡реНрдпрдХреНрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рд▓рд╛рдЗрди рдХреЗ рд╕рд╛рде рдПрдХ рд░реЗрдЦреАрдп рдорд╛рд░реНрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдЧрд┐рдирдирд╛ рдЖрд╕рд╛рди рд╣реИред O (n) рд╕рдордп рдореЗрдВ рд╕рднреА рдПрдХ рдмрд╛рд░ред рдкреА рдХреА рд╢рдХреНрддрд┐рдпреЛрдВ рдХреЛ рднреА рдЕрдЧреНрд░рд┐рдо рдореЗрдВ рдЧрдгрдирд╛ рдХреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдП рдФрд░ рдПрдХ рд╕рд░рдгреА рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдХреЛрдб рдЙрджрд╛рд╣рд░рдг:

 //      p,     pow[0] = 1; for (int i = 1; i <= MAX; i++) { pow[i] = pow[i - 1] * p; } //     s hs[0] = s[0]; for (int i = 1; i < n; i++) { hs[i] = hs[i - 1] + pow[i] * s[i]; } //     t ht[0] = t[0]; for (int i = 1; i < m; i++) { ht[i] = ht[i - 1] + pow[i] * t[i]; } 

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдЕрдм рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рд╢рд╕реНрддреНрд░ рд╣реИрдВ рдФрд░ рдУ (1) рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рднреА рд╕рдмреНрд╕рдЯреНрд░рд┐рдВрдЧ рдХреА рддреБрд▓рдирд╛ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИрдВред рд▓реЗрдХрд┐рди рд╕рдм рдХреБрдЫ рдЗрддрдирд╛ рд╕рд░рд▓ рдирд╣реАрдВ рд╣реИ: рдЧрдгрд┐рддреАрдп рд╕реВрддреНрд░реЛрдВ рдХреЛ рдХреБрдЫ рд╢реЛрдзрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рд╕рдорд╛рди рдХреЛрдб:
 if ((hs[R] - hs[L - 1]) / pow[L] == (ht[Y] - ht[X - 1]) / pow[X]) { ... } 
рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред

рдЕрдм рд╣рдо рдЙрди рдХрд╛рд░реНрдпреЛрдВ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВрдЧреЗ рдЬрд╣рд╛рдБ рд╣реИрд╢ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рд╣реИрд╢ рдЯрд╛рд╕реНрдХ


1. рдЙрдкрдЬрд╛рдКрдкрди рдХреА рддреБрд▓рдирд╛

рдкрд╣рд▓рд╛, рдФрд░ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг, рдЕрдиреБрдкреНрд░рдпреЛрдЧ, рдЬреИрд╕рд╛ рдХрд┐ рдкрд╣рд▓реЗ рд╣реА рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рджреЛ рдкрджрд╛рд░реНрдереЛрдВ рдХреА рддреНрд╡рд░рд┐рдд рддреБрд▓рдирд╛ рд╣реИ - рд╣реИрд╢ рдХреЗ рд╕рд╛рде рдЕрдиреНрдп рд╕рднреА рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдЗрд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╣реИрдВред рдЕрдВрддрд┐рдо рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рдХреЛрдб рдмрд▓реНрдХрд┐ рдмреЛрдЭрд┐рд▓ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдПрдХ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдХреЛрдб рд▓рд┐рдЦреВрдВрдЧрд╛ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдирд┐рдореНрди рдлрд╝рдВрдХреНрд╢рди рд╕рдмрд╕реНрдЯреНрд░рд┐рдВрдЧ s L..R рдХреА рдЧрдгрдирд╛ p L рд╕реЗ рдЧреБрдгрд╛ рдХрд░рддрд╛ рд╣реИ:
 long getHash(long[] h, int L, int R) { long result = h[R]; if (L > 0) result -= h[L - 1]; return result; } 

рдЕрдм, рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрдВрдХреНрддрд┐ рдХреЗ рд╕рд╛рде рджреЛ рдкрджрд╛рд░реНрдереЛрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рддреЗ рд╣реИрдВ:
 if (getHash(hs, L, R) * pow[X] == getHash(ht, X, Y) * pow[L]) { ... } 

рдкреА рдХреА рд╢рдХреНрддрд┐рдпреЛрдВ рджреНрд╡рд╛рд░рд╛ рдЧреБрдгрд╛ рдХреЛ "рдПрдХ рд╢рдХреНрддрд┐ рдореЗрдВ рдХрдореА" рдХрд╣рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдкрд╣рд▓рд╛ рд╣реИрд╢ рдкреА рдПрд▓ рд╕реЗ рдЧреБрдгрд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░ рджреВрд╕рд░рд╛ рдкреА рдПрдХреНрд╕ рджреНрд╡рд╛рд░рд╛ рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рддреБрд▓рдирд╛ рд╕рд╣реА рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП, рдЙрдиреНрд╣реЗрдВ рд▓рд╛рдкрддрд╛ рдХрд╛рд░рдХ рд╕реЗ рдЧреБрдгрд╛ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдиреЛрдЯ: рдпрд╣ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ рдХрд┐ рдЕрдЧрд░ рд╕рдмрд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреА рд▓рдВрдмрд╛рдИ рдореЗрд▓ рдЦрд╛рддреА рд╣реИ рддреЛ рдкрд╣рд▓реЗ рдЪреЗрдХ рдХрд░реЗрдВред рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рд╕рд┐рджреНрдзрд╛рдВрдд рдореЗрдВ рд▓рд╛рдЗрдиреЗрдВ рд╕рдорд╛рди рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреА рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдЖрдк рдЙрдкрд░реЛрдХреНрдд рд╕реНрдерд┐рддрд┐ рдХреА рдЬрд╛рдВрдЪ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред

2. O (n + m) рдХреЗ рд▓рд┐рдП рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рдПрдХ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд▓рд┐рдП рдЦреЛрдЬреЗрдВ

Hashes рдЖрдк рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рдПрдХ asymptotically рдХрдо рд╕реЗ рдХрдо рд╕рдордп рдореЗрдВ рдПрдХ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд▓рд┐рдП рдЦреЛрдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВред рдпрд╣ рддрдерд╛рдХрдерд┐рдд рд░рдмрд┐рди-рдХрд╛рд░реНрдк рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЪрд▓реЛ рд▓рдВрдмрд╛рдИ n рдХрд╛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ s рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╣рдо рд▓рдВрдмрд╛рдИ m рдХреЗ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ t рдХреА рд╕рднреА рдШрдЯрдирд╛рдУрдВ рдХреЛ рдЦреЛрдЬрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рд╕реНрдЯреНрд░рд┐рдВрдЧ t (рд╕рдВрдкреВрд░реНрдг рд╕реНрдЯреНрд░рд┐рдВрдЧ) рдХреЗ рд╣реИрд╢ рдФрд░ рд╕реНрдЯреНрд░рд┐рдВрдЧ s рдХреЗ рд╕рднреА рдЙрдкрд╕рд░реНрдЧреЛрдВ рдХреЗ рд╣реИрд╢ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдПрдВ, рдФрд░ рдлрд┐рд░ рд╣рдо рд╕реНрдЯреНрд░рд┐рдВрдЧ s рдХреЗ рд╕рд╛рде рд▓рдВрдмрд╛рдИ m рдХреА рдПрдХ рд╡рд┐рдВрдбреЛ рдХреЗ рд╕рд╛рде рдЖрдЧреЗ рдмрдврд╝реЗрдВрдЧреЗ, рдЬрд┐рд╕рдореЗрдВ рд╕рдмрд╕реНрдЯреНрд░рд┐рдВрдЧ s i..i + m-1 рдХреА рддреБрд▓рдирд╛ рдХреА рдЬрд╛рдПрдЧреА ред
рдХреЛрдб:
 //    t long ht = t[0]; for (int i = 1; i < m; i++) { ht += pow[i] * t[i]; } //    for (int i = 0; i + m <= n; i++) { if (getHash(h, i, i + m - 1) == ht * pow[i]) { //     i } } 

3. рдУ рдореЗрдВ рдПрдХ z- рд╕рдорд╛рд░реЛрд╣ рдвреВрдБрдврдирд╛ (рдПрди рд▓реЙрдЧ рдПрди)

String s рдХрд╛ z-function рдЕрд░реЗрдВрдЬ z рд╣реИ рдЬрд┐рд╕рдХрд╛ i- th рдПрд▓рд┐рдореЗрдВрдЯ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕реНрдЯреНрд░рд┐рдВрдЧ s рдореЗрдВ рдкреЛрдЬрд┐рд╢рдирд┐рдВрдЧ i рд╕реЗ рд╢реБрд░реВ рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рд╕рдмрд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд╕рдмрд╕реЗ рд▓рдВрдмреЗ рдЙрдкрд╕рд░реНрдЧ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ, рдЬреЛ рдХрд┐ рдкреВрд░реЗ string s рдХрд╛ рднреА рдЙрдкрд╕рд░реНрдЧ рд╣реИред рд╢реВрдиреНрдп рд╕реНрдерд┐рддрд┐ рдореЗрдВ z- рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдорд╛рди рд╕реНрдЯреНрд░рд┐рдВрдЧ s рдХреА рд▓рдВрдмрд╛рдИ рдХреЗ рдмрд░рд╛рдмрд░ рдорд╛рдирд╛ рдЬрд╛рдПрдЧрд╛, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдХреБрдЫ рд╕реНрд░реЛрдд рдЗрд╕реЗ рд╢реВрдиреНрдп рдХреЗ рд▓рд┐рдП рд▓реЗрддреЗ рд╣реИрдВ (рд▓реЗрдХрд┐рди рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИ)ред

рдмреЗрд╢рдХ, рдУ (рдПрди) рдореЗрдВ рдЬреЗрдб-рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╣реИ ред рд▓реЗрдХрд┐рди рдЬрдм рдЖрдкрдХреЛ рдкрддрд╛ рдирд╣реАрдВ рд╣реИ рдпрд╛ рдпрд╛рдж рдирд╣реАрдВ рд╣реИ (рдФрд░ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдмреЛрдЭрд┐рд▓ рд╣реИ), рд╣реИрд╢ рдмрдЪрд╛рд╡ рдореЗрдВ рдЖрддреЗ рд╣реИрдВред

рд╡рд┐рдЪрд╛рд░ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ: рдкреНрд░рддреНрдпреЗрдХ i = 0, 1, ..., n-1 рдХреЗ рд▓рд┐рдП, рд╣рдо z рдХреЗ рд▓рд┐рдП рдПрдХ рджреНрд╡рд┐рдЖрдзрд╛рд░реА рдЦреЛрдЬ рджреНрд╡рд╛рд░рд╛ рдЦреЛрдЬ рдХрд░реЗрдВрдЧреЗ, рдЕрд░реНрдерд╛рддред рдкреНрд░рддреНрдпреЗрдХ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдкрд░, рд╕рдВрднрд╛рд╡рд┐рдд рдореВрд▓реНрдпреЛрдВ рдХреА рд╕реАрдорд╛ рдХреЛ рдЖрдзрд╛ рдХрд░ рджрд┐рдпрд╛ред рдпрд╣ рд╕рд╣реА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╕рдорд╛рдирддрд╛ s 0..k-1 = s i..i + k-1 рдЬрд░реВрд░реА рд╕рднреА рдХреЗ рд▓рд┐рдП z i рд╕реЗ рдХрдо рд╣реИ, рдФрд░ рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдмрдбрд╝реЗ k рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рд╣реИред

рдХреЛрдб:
 int[] z = new int[n]; for (int i = 0; i < n; i++) { int left = 1, right = n - i; //    while (left <= right) { //  middle -   int middle = (left + right) / 2; //  ,    s[0..middle-1]  s[i..i+middle-1] if (getHash(h, 0, middle - 1) * pow[i] == getHash(h, i, i + middle - 1)) { //  ,      middle,      z[i] = middle; left = middle + 1; } else { //   ,     right = middle - 1; } } } 

4. рдУ (рдПрди рд▓реЙрдЧ рдПрди) рдореЗрдВ рд▓реЗрдХреНрд╕реЛрдЧреНрд░рд╛рдлрд┐рдХ рд░реВрдк рд╕реЗ рдиреНрдпреВрдирддрдо рдЪрдХреНрд░реАрдп рд▓рд╛рдЗрди рдмреНрд░реЗрдХ рдХреЗ рд▓рд┐рдП рдЦреЛрдЬреЗрдВред

рдПрдХ рдбреБрд╡рд▓ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╣реИ рдЬреЛ рд╣рдореЗрдВ рдУ (рдПрди) рдореЗрдВ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдХреБрдЫ рдХрд╛рдлреА рдордЬрдмреВрдд рдУрд▓рдВрдкрд┐рдпрд╛рдб рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдЬрд╛рдирддрд╛ рд╣реВрдВ рдЬрд┐рдиреНрд╣реЛрдВрдиреЗ рдЗрд╕рдХрд╛ рдкрддрд╛ рдирд╣реАрдВ рд▓рдЧрд╛рдпрд╛ рд╣реИред рдЬрдм рддрдХ рд╡реЗ рдЗрд╕реЗ рд╕рдордЭрддреЗ рд╣реИрдВ, рд╣рдо рдлрд┐рд░ рд╕реЗ рд╣реИрд╢ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред

рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рд╕рдмрд╕реЗ рдЕрдЪреНрдЫреЗ (рд╢рд╛рдмреНрджрд┐рдХ рд░реВрдк рд╕реЗ рдиреНрдпреВрдирддрдо) рдЙрддреНрддрд░ рдХреЗ рд▓рд┐рдП рд╕реНрдЯреНрд░рд┐рдВрдЧ рдПрд╕ рд▓реЗрддреЗ рд╣реИрдВред рдлрд┐рд░, рдкреНрд░рддреНрдпреЗрдХ рдЪрдХреНрд░реАрдп рдкрд╛рд░реА рдХреЗ рд▓рд┐рдП, рдПрдХ рджреНрд╡рд┐рдЖрдзрд╛рд░реА рдЦреЛрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рд╣рдо рдЗрд╕ рдкрд╛рд░реА рдХреЗ рдЕрдзрд┐рдХрддрдо рд╕рд╛рдорд╛рдиреНрдп рдЙрдкрд╕рд░реНрдЧ рдХреА рд▓рдВрдмрд╛рдИ рдФрд░ рд╡рд░реНрддрдорд╛рди рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдЙрддреНрддрд░ рдкрд╛рддреЗ рд╣реИрдВред рдЙрд╕рдХреЗ рдмрд╛рдж, рдЗрд╕ рдЙрдкрд╕рд░реНрдЧ рдХреЗ рдмрд╛рдж рдХреЗ рдкрд╛рддреНрд░реЛрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ рдФрд░, рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рддреЛ рдЙрддреНрддрд░ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВред
рд╣рдо рдпрд╣ рднреА рдзреНрдпрд╛рди рджреЗрддреЗ рд╣реИрдВ рдХрд┐ рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП рд╕реНрдЯреНрд░рд┐рдВрдЧ рдПрд╕ рдХреЛ рдЕрдкрдиреЗ рдЖрдк рдореЗрдВ рд╡рд┐рд╢реЗрд╖рддрд╛ рджреЗрдиреЗ рдХреА рд╕рд┐рдлрд╛рд░рд┐рд╢ рдХреА рдЬрд╛рддреА рд╣реИ - рдЖрдкрдХреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдПрд╕ рдХреЗ рдкрд╛рддреНрд░реЛрдВ рддрдХ рдкрд╣реБрдВрдЪрддреЗ рд╕рдордп рдореЙрдбреБрд▓реЛ рдСрдкрд░реЗрд╢рди рдирд╣реАрдВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдкрд╣рд▓реЗ рд╣реА рдХрд┐рдпрд╛ рдЬрд╛ рдЪреБрдХрд╛ рд╣реИред

рдХреЛрдб:
 int bestPos = 0; for (int i = 1; i < n; i++) { int left = 1, right = n, length = 0; //  length -     while (left <= right) { int middle = (left + right) / 2; if (getHash(h, bestPos, bestPos + middle - 1) * pow[i] == getHash(h, i, i + middle - 1) * pow[bestPos]) { length = middle; left = middle + 1; } else { right = middle - 1; } } //          //      n, //       , //      if (length < n && s[i + length] < s[bestPos + length]) { bestPos = i; } } 

рдиреЛрдЯ: рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдПрдХ рддреБрд▓рдирд┐рддреНрд░ рд▓реВрдк рдХреЗ for рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рд▓реЗрдХреНрд╕рд┐рдХреЛрдЧреНрд░рд╛рдлрд┐рдХ рд░реВрдк рд╕реЗ рджреЛ рдЪрдХреНрд░реАрдп рдкрд╛рд░рд┐рдпреЛрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рд╕рднреА рдЪрдХреНрд░реАрдп рдкрд╛рд░рд┐рдпреЛрдВ рдХреЛ O (n log 2 n) рдореЗрдВ рд╕реЙрд░реНрдЯ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИред

5. рдУ (рдПрди рд▓реЙрдЧ рдПрди) рдХреЗ рд▓рд┐рдП рд▓рд╛рдЗрди рдореЗрдВ рд╕рднреА palindromes рдХреЗ рд▓рд┐рдП рдЦреЛрдЬреЗрдВред

рдлрд┐рд░, рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдорд╛рдзрд╛рди O (n) рдореЗрдВ рд╣реИ ред рдФрд░ рдлрд┐рд░, рд╣рдо рдЗрд╕реЗ рд╣реИрд╢ рдХреЗ рд╕рд╛рде рд╣рд▓ рдХрд░реЗрдВрдЧреЗред

рдпрджрд┐ L = s R , s L + 1 = s R-1 рдЗрддреНрдпрд╛рджрд┐ рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рддреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди L L.R рдХреЛ рдПрдХ рддрд╛рд▓ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕реЗ рд░реВрд╕реА рдореЗрдВ рдбрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдпрд╣ рдмрд╛рдПрдВ рд╕реЗ рджрд╛рдПрдВ, рдФрд░ рджрд╛рдПрдВ рд╕реЗ рдмрд╛рдПрдВ рд╕реЗ рдЙрд╕реА рддрд░рд╣ рдкрдврд╝рд╛ рдЬрд╛рддрд╛ рд╣реИред

рд╢рд╛рдпрдж рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЬрд╛рдирддреЗ рд╣реИрдВ рдпрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рддреЗ рд╣реИрдВ рдХрд┐ рд╣реИрд╢ рдХрд╛ рдЗрд╕рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ рдРрд░реЗ h[] рдЕрд▓рд╛рд╡рд╛ рд╕рдмрд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рд╣реИрд╢ рдпреБрдХреНрдд 0..0 , s 0..1 , ..., s 0..n-2 , s 0..n-1 , рд╣рдо рджреВрд╕рд░реЗ рдРрд░ rh[] рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ (рдХреЗ рд▓рд┐рдП) "рдЙрд▓рдЯрд╛" рд▓рд╛рдЗрди), рдЬрд┐рд╕реЗ рд╣рдо рджрд╛рдИрдВ рд╕реЗ рдмрд╛рдИрдВ рдУрд░ рдШреВрдореЗрдВрдЧреЗред рдЗрд╕рдореЗрдВ рддрджрдиреБрд╕рд╛рд░ рд╣реИрд╢ рд╣реЛрдЧрд╛ 0..n-1 , s 1..n-1 , ..., s n-2..n-1 , s n-1..n-1 :
 rh[n - 1] = s[n - 1]; for (int i = n - 2, j = 1; i >= 0; i--, j++) { rh[i] = rh[i + 1] + pow[j] * s[i]; } 

рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕реНрдкрд╖реНрдЯ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдХреИрд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдП рдХрд┐ рдпрджрд┐ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдУ (1) рдХреЗ рдмрд╛рдж рдПрдХ рдкреИрд▓рд┐рдВрдбреНрд░реЛрдо рд╣реИред рдореИрдВ getHashHash () рдлрд╝рдВрдХреНрд╢рди рдХреЛ getHash () рдХреЗ рд╕рдорд╛рди рд▓рд┐рдЦреВрдВрдЧрд╛, рдФрд░ рдлрд┐рд░ рдореИрдВ рдЖрд╡рд╢реНрдпрдХ рддреБрд▓рдирд╛ рдХреА рд╕реНрдерд┐рддрд┐ рджреВрдВрдЧрд╛ред рдЖрдк рдЧрдгрд┐рддреАрдп рдЧрдгрдирд╛ рдХрд░рдХреЗ рдЗрд╕ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреА рд╢реБрджреНрдзрддрд╛ рдХреЛ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рд▓реЗрдЦ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдП рдЧрдП рд╣реИрдВред
 long getRevHash(long[] rh, int L, int R) { long result = rh[L]; if (R < n - 1) result -= rh[R + 1]; return result; } boolean isPalindrome(long[] h, long[] rh, long[] pow, int L, int R) { return getHash(h, L, R) * pow[n - R - 1] == getRevHash(rh, L, R) * pow[L]; } 

рдЕрдм рдкрдВрдХреНрддрд┐ рдореЗрдВ i рдХреА рд╕реНрдерд┐рддрд┐ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рдЖрдЗрдП рд╕реНрдерд┐рддрд┐ i рдкрд░ рдХреЗрдВрджреНрд░рд┐рдд рд╡рд┐рд╖рдо рд▓рдВрдмрд╛рдИ d рдХрд╛ рдПрдХ рддрд╛рд▓реБ (рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рд▓рдВрдмрд╛рдИ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, i-1 рдФрд░ i рдХреЗ рдмреАрдЪ рдХреЗрдВрджреНрд░рд┐рдд) рд╣реЛред рдпрджрд┐ рдЖрдк рдЗрд╕рдХреЗ рдХрд┐рдирд╛рд░реЛрдВ рд╕реЗ рдПрдХ рдкрд╛рддреНрд░ рдХреЛ рдХрд╛рдЯрддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдПрдХ рдкреИрд▓рд┐рдВрдбреНрд░реЛрдо рд░рд╣реЗрдЧрд╛ред рдФрд░ рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рддрдм рддрдХ рдЬрд╛рд░реА рд░рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬрдм рддрдХ рдХрд┐ рдЗрд╕рдХреА рд▓рдВрдмрд╛рдИ рд╢реВрдиреНрдп рдХреЗ рдмрд░рд╛рдмрд░ рди рд╣реЛ рдЬрд╛рдПред
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдпрд╣ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдкреНрд░рддреНрдпреЗрдХ рд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП 2 рдорд╛рдиреЛрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ: рд╡рд┐рд╖рдо рд▓рдВрдмрд╛рдИ рдХреЗ рдХрд┐рддрдиреЗ palindromes рд╕реНрдерд┐рддрд┐ i рдореЗрдВ рдПрдХ рдХреЗрдВрджреНрд░ рдХреЗ рд╕рд╛рде рдореМрдЬреВрдж рд╣реИрдВ, рдФрд░ рдХрд┐рддрдиреЗ рд▓рдВрдмрд╛рдИ рдХреЗ palindromes i-1 рдФрд░ i рдХреЗ рдмреАрдЪ рдХреЗрдВрджреНрд░ рдХреЗ рд╕рд╛рде рдореМрдЬреВрдж рд╣реИрдВред рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпреЗ 2 рдореВрд▓реНрдп рдПрдХ рджреВрд╕рд░реЗ рд╕реЗ рдмрд┐рд▓реНрдХреБрд▓ рд╕реНрд╡рддрдВрддреНрд░ рд╣реИрдВ, рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЕрд▓рдЧ рд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рд╣рдо рдкрд╣рд▓реЗ рдХреА рддрд░рд╣, рдмрд╛рдЗрдирд░реА рдЦреЛрдЬ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ:
 int[] oddCount = new int[n]; for (int i = 0; i < n; i++) { int left = 1, right = min(i + 1, n - i); while (left <= right) { int middle = (left + right) / 2; if (isPalindrome(h, rh, pow, i - middle + 1, i + middle - 1)) { oddCount[i] = middle; left = middle + 1; } else { right = middle - 1; } } } int[] evenCount = new int[n]; for (int i = 0; i < n; i++) { int left = 1, right = min(i, n - i); while (left <= right) { int middle = (left + right) / 2; if (isPalindrome(h, rh, pow, i - middle, i + middle - 1)) { evenCount[i] = middle; left = middle + 1; } else { right = middle - 1; } } } 

рдЕрдм рдЖрдк рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдкрдВрдХреНрддрд┐ рдореЗрдВ рд╕рднреА palindromes рдХреА рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛ рдпрд╛ рдЕрдзрд┐рдХрддрдо palindrome рдХреА рд▓рдВрдмрд╛рдИ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВред рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдХреЗрдВрджреНрд░рд┐рдд рдЕрдзрд┐рдХрддрдо рд╡рд┐рдЪрд┐рддреНрд░ 2 * oddCount[i] - 1 рдХреА рд▓рдВрдмрд╛рдИ рдХреЛ рдореИрдВ 2 * oddCount[i] - 1 рд░реВрдк рдореЗрдВ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЕрдзрд┐рдХрддрдо 2 * evenCount[i] ред
рдореБрдЭреЗ рдЖрдкрдХреЛ рдПрдХ рдмрд╛рд░ рдлрд┐рд░ рдпрд╛рдж рджрд┐рд▓рд╛рдирд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рд╕рдорд╛рди рдФрд░ рд╡рд┐рд╖рдо рд▓рдВрдмрд╛рдИ рд╡рд╛рд▓реЗ рдкреИрд▓рдВрдбреНрд░реЛрдореЛрдВ рд╕реЗ рдЕрдзрд┐рдХ рд╕рд╛рд╡рдзрд╛рди рд░рд╣рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ - рдПрдХ рдирд┐рдпрдо рдХреЗ рд░реВрдк рдореЗрдВ, рдЙрдиреНрд╣реЗрдВ рдПрдХ-рджреВрд╕рд░реЗ рд╕реЗ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдореИрдЯреНрд░рд┐рдХреНрд╕ рд╣реИрд╢


рдЕрдВрдд рдореЗрдВ, рд╣реИрд╢ рдХреЗ рдЕрдзрд┐рдХ рдкрд░рд┐рд╖реНрдХреГрдд рдЙрдкрдпреЛрдЧреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рдЕрдм рд╣рдорд╛рд░рд╛ рд╕реНрдерд╛рди рджреЛ-рдЖрдпрд╛рдореА рд╣реЛрдЧрд╛, рдФрд░ рд╣рдо рдЙрдкрдорд╛рддреНрд░рд╛рдУрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░реЗрдВрдЧреЗред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рджреЛ-рдЖрдпрд╛рдореА рдорд╛рдорд▓реЗ рдореЗрдВ рд╣реИрд╢ рдмрд╣реБрдд рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рд╣реИрдВ (рдореИрдВрдиреЗ рдХрднреА рднреА рддреАрди-рдЖрдпрд╛рдореА рдпрд╛ рдЕрдзрд┐рдХ рдирд╣реАрдВ рджреЗрдЦрд╛ рд╣реИ)ред

рдЕрдм рд╕рдВрдЦреНрдпрд╛ p рдФрд░ pow рд╕рд░рдгреА рдХреЗ рдмрдЬрд╛рдп, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕рдВрдЦреНрдпрд╛рдПрдБ p , q рдФрд░ рджреЛ pow1 , pow2 : рдкреНрд░рддреНрдпреЗрдХ рджрд┐рд╢рд╛ рдореЗрдВ рдПрдХ рд╕рдВрдЦреНрдпрд╛ рдФрд░ рдПрдХ рд╕рд░рдгреА: рд▓рдВрдмрд╡рдд рдФрд░ рдХреНрд╖реИрддрд┐рдЬ рд░реВрдк рд╕реЗред

рд╣реИрд╢ рдореЗрдВ 0..n-1, 0..m-1 рдХреЛ рд╕рднреА i = 0, ..., n-1 , j = 0, ..., рдХреА рдорд╛рддреНрд░рд╛ рд╕реЗ m-1 рдХрд╣рд╛ рдЬрд╛рдПрдЧрд╛ред рдЗ рдЬ ред

рдЕрдм рд╣рдо рд╕реАрдЦреЗрдВрдЧреЗ рдХрд┐ рдКрдкрд░реА рдмрд╛рдПрдБ рддрддреНрд╡ 00 рд╡рд╛рд▓реЗ рдЙрдкрдорд╛рддреНрд░рд╛рдУрдВ рдХреЗ рд╣реИрд╢ рдХреА рдЧрд┐рдирддреА рдХреИрд╕реЗ рдХрд░реЗрдВред рдЬрд╛рд╣рд┐рд░ рд╣реИ, рд╣реИрд╢ (рдПрдХ 0..0, 0..0 ) = рдПрдХ 00 ред рдпрд╣ рд▓рдЧрднрдЧ рд╕рдорд╛рди рд░реВрдк рд╕реЗ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рд╕рднреА j = 1, ..., m-1 рд╣реИрд╢ (рдПрдХ 0..0, 0..j ) = рд╣реИрд╢ (рдПрдХ 0..0, 0..j-1 ) + q рдХреЗ рд▓рд┐рдП j a 0j , рд╕рднреА i = 1, ..., n-1 рд╣реИрд╢ (рдПрдХ 0..i, 0..0 ) = рд╣реИрд╢ (рдПрдХ 0..i-1, 0..0 ) + p i a рдХреЗ рд▓рд┐рдП i0 ред рдпрд╣ рд╕реАрдзреЗ рдПрдХ рдЖрдпрд╛рдореА рдорд╛рдорд▓реЗ рд╕реЗ рд╣реЛрддрд╛ рд╣реИред

рд╕рдмрдореЗрдЯреНрд░рд┐рдХреНрд╕ рдХреЗ рд╣реИрд╢ рдХреА рдЧрдгрдирд╛ рдХреИрд╕реЗ рдХрд░реЗрдВ 0..i, 0..рдЬреЗ ? рдХреЛрдИ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╣реИрд╢ (рдПрдХ 0..рдЖрдИ, 0..рдЬреЗ ) = рд╣реИрд╢ (рдПрдХ 0..рдЖрдИ -1, 0..рдЬреЗ ) + рд╣реИрд╢ (рдПрдХ 0. рдЖрдИ, 0..рдЬреЗ -1 ) - рд╣реИрд╢ ( 0..i-1, 0..j-1 ) + p i q j a ij ред рдпрд╣ рд╕реВрддреНрд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдмрд╛рддреЛрдВ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ: рд╕рднреА рд╢рдмреНрджреЛрдВ (рд╣реИрд╢, рдореБрдЭреЗ рдпрд╛рдж рд╣реИ рдХрд┐ рдпрд╣ рдХрдИ рд╢рд░реНрддреЛрдВ рдХрд╛ рдпреЛрдЧ рд╣реИ) рдХреЛ рдЬреЛрдбрд╝ рджреЗрдВ рдЬреЛ рдЙрдкрдорд╛рддреНрд░рд╛рдУрдВ рдХреЗ рд╣реИрд╢ рдХреЛ 0..i-1, 0..j рдФрд░ 0._i, 0..j-1 рдмрдирд╛рддреЗ рд╣реИрдВред ред рдЙрд╕реА рд╕рдордп, рд╣рдордиреЗ рдЙрди рд╢рдмреНрджреЛрдВ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрд╛ рдЬреЛ рд╕рдмрдореЗрдЯреНрд░рд┐рдХреНрд╕ рдХреЛ 0..i-1, 0..j-1 рджреЛ рдмрд╛рд░ рдмрдирд╛рддреЗ рд╣реИрдВ , рдЗрд╕рд▓рд┐рдП рд╣рдо рдЙрдиреНрд╣реЗрдВ рдШрдЯрд╛рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдПрдХ рдмрд╛рд░ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рдПред рдЕрдм, рдХреЗрд╡рд▓ рдПрдХ рддрддреНрд╡ рдЬреЛ p рдФрд░ q рдХреА рд╕рдВрдмрдВрдзрд┐рдд рд╢рдХреНрддрд┐рдпреЛрдВ рд╕реЗ рдЧреБрдгрд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рд╡рд╣ рдЧрд╛рдпрдм рд╣реИред

рд▓реЗрдЦ рдХреЗ рдкрд╣рд▓реЗ рднрд╛рдЧ рдХреЗ рд░реВрдк рдореЗрдВ рд▓рдЧрднрдЧ рд╕рдорд╛рди рдХрд╛рд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП (рдХреНрдпрд╛ рдЖрдкрдиреЗ рдкрд╣рд▓реЗ рд╣реА рд╕рдорд╛рд╡реЗрд╢рди-рдмрд╣рд┐рд╖реНрдХрд░рдг рдлрд╛рд░реНрдореВрд▓реЗ рдХреА рднрд╛рдЧреАрджрд╛рд░реА рдкрд░ рдзреНрдпрд╛рди рджрд┐рдпрд╛ рд╣реИ?), рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдордирдорд╛рдиреЗ рдврдВрдЧ рд╕реЗ рд╕рдмрдореИрдЯрд┐рдХреНрд╕ рдХреЗ рд╣реИрд╢ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдПрдХ X1..x2, y1 -y2 :
 long getMatrixHash(long[][] h, int x1, int x2, int y1, int y2) { long result = h[x2][y2]; if (x1 > 0) result -= h[x1 - 1][y2]; if (y1 > 0) result -= h[x2][y1 - 1]; if (x1 > 0 && y1 > 0) result += h[x1 - 1][y1 - 1]; return result; } 

рдпрд╣ рдлрд╝рдВрдХреНрд╢рди submatrix рдХреЗ рд╣реИрд╢ рдХреЛ рдПрдХ X1..x2, y1..y2 рдмрд╛рд░ p X1 q y1 рд▓реМрдЯрд╛рддрд╛ рд╣реИ ред

рджреЛ рдЙрдкрдорд╛рдУрдВ рдХреА рдПрдХ ax1..ax2, ay1..ay2 рдФрд░ рдПрдХ bx1..bx2, by1..by2 рдХреА рддреБрд▓рдирд╛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреА рдЬрд╛рддреА рд╣реИ:
 if (getMatrixHash(h, ax1, ax2, ay1, ay2) * pow1[bx1] * pow2[by1] == getMatrixHash(h, bx1, bx2, by1, by2) * pow1[ax1] * pow2[ay1]) { ... } 

рд╣реИрд╢ рд╕рдмрд╕реЗ рдмрдбрд╝реА рд╕рдордорд┐рддрд┐ рд╕рдмрдореЗрдЯреНрд░рд┐рдХреНрд╕ рдЦреЛрдЬрдиреЗ рдФрд░ рдЙрдирд╕реЗ рдорд┐рд▓рддреА-рдЬреБрд▓рддреА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рднреА рд╣рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдФрд░ рдореБрдЭреЗ рдпрд╣ рдкрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдЗрд╕ рдХрд╛рд░реНрдп рдХреЛ рдЧрддрд┐ рдФрд░ рд╕рд░рд▓рддрд╛ рдореЗрдВ рд╣реИрд╢ рдХреЗ рдмрд░рд╛рдмрд░ рдХрд░рддрд╛ рд╣реИред рдпрд╣рд╛рдВ, рдЙрдиреНрд╣реАрдВ рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдХ рдЖрдпрд╛рдореА рдорд╛рдорд▓реЗ рдореЗрдВ рдкреИрд▓рд┐рдиреНрдбреНрд░реЛрдо рдХреА рдЦреЛрдЬ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдпрд╛рдиреА, "рдЙрд▓рдЯрд╛" рд╣реИрд╢ рдХреЛ рджрд╛рдПрдВ рд╕реЗ рдмрд╛рдПрдВ рдФрд░ рдиреАрдЪреЗ рд╕реЗ рдКрдкрд░ рддрдХ, рдмрд┐рди рдЦреЛрдЬ рдХреЛ рд╕рдо рдФрд░ рд╡рд┐рд╖рдо рдХреЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░реЗрдВ)ред рдореЗрд░рд╛ рд╕реБрдЭрд╛рд╡ рд╣реИ рдХрд┐ рдЖрдк рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╕реНрд╡рдпрдВ рд╣рд▓ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ - рдпрд╣ рд▓реЗрдЦ рдЖрдкрдХреА рдорджрдж рдХрд░реЗрдЧрд╛!

рдирд┐рд╖реНрдХрд░реНрд╖


рддреЛ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╣рдорд╛рд░реЗ рдирд┐рдкрдЯрд╛рди рдореЗрдВ рдПрдХ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдЙрдкрдХрд░рдг рд╣реИ, рдЬреЛ рд╣рдореЗрдВ рдХрдИ рдЪреАрдЬреЛрдВ рдХреЛ рдпрд╛ рддреЛ рд╕рд░реНрд╡реЛрддреНрддрдо рд╕рдВрднрд╡ рд╕реНрдкрд░реНрд╢реЛрдиреНрдореБрдЦ рджрд╡рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдпрд╛ рд╡рд┐рд╢реЗрд╖ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдХреЗрд╡рд▓ рдереЛрдбрд╝рд╛ (рд▓рдШреБрдЧрдгрдХ рд╕рдордп) рдзреАрдорд╛ рд╣реИред рдмреБрд░рд╛ рдирд╣реАрдВ рд╣реИ, рд╣реИ рдирд╛?

Source: https://habr.com/ru/post/In142589/


All Articles