рд╣реЗрд▓реЛ, рд╣реИрдмрд░ред рдЖрдЬ рдореИрдВ рд▓рд┐рдЦреВрдВрдЧрд╛ рдХрд┐ рдЖрдк рд╡рд┐рднрд┐рдиреНрди рдПрд▓реНрдЧреЛрд░рд┐рдердо рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдкрдж рд╣реИрд╢ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдЗрд╕рдХреЗ рдмрд╛рдж рдмрд╕ рд╣реИрд╢)ред
рдкрд░рд┐рдЪрдп
рдЪрд▓рд┐рдП рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╣реИ
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) рд╕рдордп рдореЗрдВ рд╕рднреА рдПрдХ рдмрд╛рд░ред
рдкреА рдХреА рд╢рдХреНрддрд┐рдпреЛрдВ рдХреЛ рднреА рдЕрдЧреНрд░рд┐рдо рдореЗрдВ рдЧрдгрдирд╛ рдХреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдП рдФрд░ рдПрдХ рд╕рд░рдгреА рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдХреЛрдб рдЙрджрд╛рд╣рд░рдг:
рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдЕрдм рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рд╢рд╕реНрддреНрд░ рд╣реИрдВ рдФрд░
рдУ (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 рдХреА рддреБрд▓рдирд╛ рдХреА
рдЬрд╛рдПрдЧреА ред
рдХреЛрдб:
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;
4. рдУ (рдПрди рд▓реЙрдЧ рдПрди) рдореЗрдВ рд▓реЗрдХреНрд╕реЛрдЧреНрд░рд╛рдлрд┐рдХ рд░реВрдк рд╕реЗ рдиреНрдпреВрдирддрдо рдЪрдХреНрд░реАрдп рд▓рд╛рдЗрди рдмреНрд░реЗрдХ рдХреЗ рд▓рд┐рдП рдЦреЛрдЬреЗрдВред
рдПрдХ рдбреБрд╡рд▓ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╣реИ рдЬреЛ рд╣рдореЗрдВ
рдУ (рдПрди) рдореЗрдВ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдХреБрдЫ рдХрд╛рдлреА рдордЬрдмреВрдд рдУрд▓рдВрдкрд┐рдпрд╛рдб рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдЬрд╛рдирддрд╛ рд╣реВрдВ рдЬрд┐рдиреНрд╣реЛрдВрдиреЗ рдЗрд╕рдХрд╛ рдкрддрд╛ рдирд╣реАрдВ рд▓рдЧрд╛рдпрд╛ рд╣реИред рдЬрдм рддрдХ рд╡реЗ рдЗрд╕реЗ рд╕рдордЭрддреЗ рд╣реИрдВ, рд╣рдо рдлрд┐рд░ рд╕реЗ рд╣реИрд╢ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред
рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рд╕рдмрд╕реЗ рдЕрдЪреНрдЫреЗ (рд╢рд╛рдмреНрджрд┐рдХ рд░реВрдк рд╕реЗ рдиреНрдпреВрдирддрдо) рдЙрддреНрддрд░ рдХреЗ рд▓рд┐рдП рд╕реНрдЯреНрд░рд┐рдВрдЧ
рдПрд╕ рд▓реЗрддреЗ рд╣реИрдВред рдлрд┐рд░, рдкреНрд░рддреНрдпреЗрдХ рдЪрдХреНрд░реАрдп рдкрд╛рд░реА рдХреЗ рд▓рд┐рдП, рдПрдХ рджреНрд╡рд┐рдЖрдзрд╛рд░реА рдЦреЛрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рд╣рдо рдЗрд╕ рдкрд╛рд░реА рдХреЗ рдЕрдзрд┐рдХрддрдо рд╕рд╛рдорд╛рдиреНрдп рдЙрдкрд╕рд░реНрдЧ рдХреА рд▓рдВрдмрд╛рдИ рдФрд░ рд╡рд░реНрддрдорд╛рди рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдЙрддреНрддрд░ рдкрд╛рддреЗ рд╣реИрдВред рдЙрд╕рдХреЗ рдмрд╛рдж, рдЗрд╕ рдЙрдкрд╕рд░реНрдЧ рдХреЗ рдмрд╛рдж рдХреЗ рдкрд╛рддреНрд░реЛрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ рдФрд░, рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рддреЛ рдЙрддреНрддрд░ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВред
рд╣рдо рдпрд╣ рднреА рдзреНрдпрд╛рди рджреЗрддреЗ рд╣реИрдВ рдХрд┐ рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП рд╕реНрдЯреНрд░рд┐рдВрдЧ
рдПрд╕ рдХреЛ рдЕрдкрдиреЗ рдЖрдк рдореЗрдВ рд╡рд┐рд╢реЗрд╖рддрд╛ рджреЗрдиреЗ рдХреА рд╕рд┐рдлрд╛рд░рд┐рд╢ рдХреА рдЬрд╛рддреА рд╣реИ - рдЖрдкрдХреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧ
рдПрд╕ рдХреЗ рдкрд╛рддреНрд░реЛрдВ рддрдХ рдкрд╣реБрдВрдЪрддреЗ рд╕рдордп рдореЙрдбреБрд▓реЛ рдСрдкрд░реЗрд╢рди рдирд╣реАрдВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдкрд╣рд▓реЗ рд╣реА рдХрд┐рдпрд╛ рдЬрд╛ рдЪреБрдХрд╛ рд╣реИред
рдХреЛрдб:
int bestPos = 0; for (int i = 1; i < n; i++) { int left = 1, right = n, length = 0;
рдиреЛрдЯ: рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдПрдХ рддреБрд▓рдирд┐рддреНрд░ рд▓реВрдк рдХреЗ
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]) { ... }
рд╣реИрд╢ рд╕рдмрд╕реЗ рдмрдбрд╝реА рд╕рдордорд┐рддрд┐ рд╕рдмрдореЗрдЯреНрд░рд┐рдХреНрд╕ рдЦреЛрдЬрдиреЗ рдФрд░ рдЙрдирд╕реЗ рдорд┐рд▓рддреА-рдЬреБрд▓рддреА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рднреА рд╣рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдФрд░ рдореБрдЭреЗ рдпрд╣ рдкрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдЗрд╕ рдХрд╛рд░реНрдп рдХреЛ рдЧрддрд┐ рдФрд░ рд╕рд░рд▓рддрд╛ рдореЗрдВ рд╣реИрд╢ рдХреЗ рдмрд░рд╛рдмрд░ рдХрд░рддрд╛ рд╣реИред рдпрд╣рд╛рдВ, рдЙрдиреНрд╣реАрдВ рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдХ рдЖрдпрд╛рдореА рдорд╛рдорд▓реЗ рдореЗрдВ рдкреИрд▓рд┐рдиреНрдбреНрд░реЛрдо рдХреА рдЦреЛрдЬ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдпрд╛рдиреА, "рдЙрд▓рдЯрд╛" рд╣реИрд╢ рдХреЛ рджрд╛рдПрдВ рд╕реЗ рдмрд╛рдПрдВ рдФрд░ рдиреАрдЪреЗ рд╕реЗ рдКрдкрд░ рддрдХ, рдмрд┐рди рдЦреЛрдЬ рдХреЛ рд╕рдо рдФрд░ рд╡рд┐рд╖рдо рдХреЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░реЗрдВ)ред рдореЗрд░рд╛ рд╕реБрдЭрд╛рд╡ рд╣реИ рдХрд┐ рдЖрдк рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╕реНрд╡рдпрдВ рд╣рд▓ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ - рдпрд╣ рд▓реЗрдЦ рдЖрдкрдХреА рдорджрдж рдХрд░реЗрдЧрд╛!
рдирд┐рд╖реНрдХрд░реНрд╖
рддреЛ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╣рдорд╛рд░реЗ рдирд┐рдкрдЯрд╛рди рдореЗрдВ рдПрдХ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдЙрдкрдХрд░рдг рд╣реИ, рдЬреЛ рд╣рдореЗрдВ рдХрдИ рдЪреАрдЬреЛрдВ рдХреЛ рдпрд╛ рддреЛ рд╕рд░реНрд╡реЛрддреНрддрдо рд╕рдВрднрд╡ рд╕реНрдкрд░реНрд╢реЛрдиреНрдореБрдЦ рджрд╡рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдпрд╛ рд╡рд┐рд╢реЗрд╖ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдХреЗрд╡рд▓ рдереЛрдбрд╝рд╛ (рд▓рдШреБрдЧрдгрдХ рд╕рдордп) рдзреАрдорд╛ рд╣реИред рдмреБрд░рд╛ рдирд╣реАрдВ рд╣реИ, рд╣реИ рдирд╛?