Sqrt рдЕрдкрдШрдЯрди (рд░реВрдЯ рдЕрдиреБрдХреВрд▓рди)

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


рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдмрдпрд╛рди

рд╣рдореЗрдВ рдПрдХ рд╕рд░рдгреА A [i] рджреА рдЬрд╛рддреА рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдлреЙрд░реНрдо рдХреЗ рдЕрдиреБрд░реЛрдз:
Naive рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди

рд╣рдо рдЖрдВрд╢рд┐рдХ рдорд╛рддреНрд░рд╛ рдХреА рдПрдХ рд╕рд░рдгреА рдХреА рдЧрдгрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЕрд░реНрдерд╛рддреН:
for(int j = 0; j < i; j++) B[j] += A[i]; 
рдФрд░ рдлрд┐рд░ рд░рд╛рд╢рд┐ рдХреЗ рдЕрдиреБрд░реЛрдз рдкрд░ [рдПрд▓; R], рд╣рдо B [R] -B [L-1] рдХреЛ рд╡рд╛рдкрд╕ рдХрд░реЗрдВрдЧреЗ рдЫрд╡рд┐ ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдПрдХ рдкрд░рд┐рд╡рд░реНрддрди рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рдиреЗ рдкрд░, рдЗрд╕реЗ рдЖрдВрд╢рд┐рдХ рд░рдХрдо (рдЗрд╕ рддрддреНрд╡ рд╕реЗ рдпреБрдХреНрдд) рдХреЗ рдкреБрдирд░реНрдЧрдгрдирд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рдФрд░, рд╕рдмрд╕реЗ рдЦрд░рд╛рдм рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдЖрджреЗрд╢ рдХрд╛ рдПрдХ рд╕реНрдкрд░реНрд╢реЛрдиреНрдореБрдЦ рдмрдирд╛ рджреЗрдЧрд╛ рдЫрд╡рд┐ рдпрд╣ рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд╣реИред

рдЕрдкрдШрдЯрди рднрд╡рди

рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реЛрдЧрд╛ рдХрд┐ рдЫрд╡рд┐ * рдЫрд╡рд┐ = рдЫрд╡рд┐ ред рдЕрд░реНрдерд╛рддреН, рдЕрдЧрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╣реИ рдЫрд╡рд┐ рддрддреНрд╡реЛрдВ, рддреЛ рд╣рдо рдЙрди рд╕рднреА рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЫрд╡рд┐ рдмреНрд▓реЙрдХ рдЬрд╣рд╛рдВ рдкреНрд░рддреНрдпреЗрдХ рд▓рдВрдмрд╛ рд╣реИ рдЫрд╡рд┐ рд╢рд╛рдпрдж рдЕрдВрддрд┐рдо рдХреЛ рдЫреЛрдбрд╝рдХрд░ред рдлрд┐рд░ рд╕рднреА рдмреНрд▓реЙрдХреЛрдВ рдХреЗ рд▓рд┐рдП рд╣рдо рдЙрд╕ рдкрд░ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рдпреЛрдЧ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВрдЧреЗ, рдЖрдк рддреБрд░рдВрдд рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╕рд╣рд╛рдпрдХ рд╕рд░рдгреА рдкрд░ рдХрдмреНрдЬрд╛ рд╣реЛ рдЬрд╛рдПрдЧрд╛ рдЫрд╡рд┐ рд╕реНрдореГрддрд┐ред
рд╣рдо sqrtSums [] рд╕рд░рдгреА рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ:
 int len = (int)sqrt(n) + 1; //  "sqrt-" int sqrtSums[MAXN], st = 0; //   for(int i = 0; i < n; i++) sqrtSums[i / len] += A[i]; 


рдЕрдиреБрд░реЛрдз рд╡рд┐рд╡рд░рдг

рд░рд╛рд╢рд┐ рдЕрдиреБрд░реЛрдз (RSQ)

рдХреНрд╡реЗрд░реА рд░рд╛рд╢рд┐ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ [рдПрд▓; рдЖрд░], рдЗрд╕рдХреЗ рд▓рд┐рдП "рддреНрд╡рд░рд┐рдд" рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП, рдкрд╣рд▓реЗ рд╕реЗ рдЙрдкрд▓рдмреНрдз рдЬрд╛рдирдХрд╛рд░реА рдХрд╛ рдЕрдзрд┐рдХрддрдо рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рд╣рдордиреЗ рдХрд╣рд╛ рд╣реИ, рд╕рдо [рдПрд▓; рдЖрд░] = рд╕рдо [0, рдЖрд░] - рд╕рдо [0; рдПрд▓ -1]ред рдпрд╣ рд╕реАрдЦрдирд╛ рд░рд╣рддрд╛ рд╣реИ рдХрд┐ рдЕрдиреБрд░реЛрдз рдХреЛ рдХреИрд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдП [0]; рдЖрд░]ред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдкрд╣рд▓реЗ рдХреБрдЫ рдЦрдВрдб ([0; len-1], [len; 2*len-1], ...) рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХреНрд╡реЗрд░реА [0] рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрдВрдЧреЗ; R], рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╣рдо sqrtSums[] рд▓рд┐рдП рдЬрд╛рдирдХрд╛рд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЫрд╡рд┐ , рдЬрдм рд╕реЗ рд╡рд╣рд╛рдБ рд╣реИрдВ рдЫрд╡рд┐ )ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдлрд╝реЙрд░реНрдо рдХреА "рдкреВрдВрдЫ" рд╣реЛрдЧреА: [k*len; k*len + delta] [k*len; k*len + delta] (рдбреЗрд▓реНрдЯрд╛ <len, рдХреНрдпреЛрдВрдХрд┐ рдЕрдиреНрдпрдерд╛, рд╣рдо рдПрдХ рдФрд░ рдЦрдВрдб [k*len; (k+1)*len-1] ) рд╢рд╛рдорд┐рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рдо рдЗрд╕реЗ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдЧрдгрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдбреЗрд▓реНрдЯрд╛ <len; рд╕реНрдкрд░реНрд╢реЛрдиреНрдореБрдЦ рдкрд░, рдЫрд╡рд┐ рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рдХрд░реЗрдЧрд╛)ред рдпрд╣рд╛рдБ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ:
 int getPartSum(int r) { int it = 0, res = 0; while((it+1) * len -1 <= r) res += sqrtSums[it++]; //  ,   for(int i = it*len; i <=r; i++) res += A[i]; // "" return res; } int getSum(int l, int r) { if(l == 0) return getPartSum(r); else return getPartSum(r) - getPartSum(l-1); } 

рдЖрдЗрдЯрдо рдкрд░рд┐рд╡рд░реНрддрди рдЕрдиреБрд░реЛрдз


рдХрдИ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдореЗрдВ, рдЗрд╕ рдХреНрд╡реЗрд░реА рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдкреЗрдбрд╝ рдХреЗ рдиреАрдЪреЗ рдЬрд╛рдиреЗ рдХреА рдЬрд╝рд░реВрд░рдд рд╣реИ, рдпрд╛ рд╣реИрд╢ рдлрд╝рдВрдХреНрд╢рди рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВ, рдпрд╛ рдХреБрдЫ рдФрд░ ... рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣рд╛рдВ рд╣рдореЗрдВ рдХреЗрд╡рд▓ 2 рдорд╛рди рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ (рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рдмрд┐рд▓реНрдХреБрд▓ рдПрдХ "sqrt рд╕реЗрдЧрдореЗрдВрдЯ" рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИ)
 int incElement(int index, int delta) { A[index] += delta; sqrtSums[index/len] += delta; } 


рд░реЗрдВрдЬ рдорд┐рди / рдореИрдХреНрд╕ / рдЬреАрд╕реАрдбреА рдХреНрд╡реЗрд░реА


RMQ рдХреНрд╡реЗрд░реАрдЬрд╝ (рд░реЗрдВрдЬ рдорд┐рди / рдореИрдХреНрд╕ рдХреНрд╡реЗрд░реА) рдХрд╛ рдЬрд╡рд╛рдм рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рд▓рдЧрднрдЧ рд╡рд╣реА рдЪреАрдЬрд╝ рдЪрд╛рд╣рд┐рдП рдЬреЛ рд░рдХрдо рдХреЗ рд▓рд┐рдП рд╣реЛрддреА рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рдЖрдЗрдЯрдо "рдмреЗрд╡рдХреВрдл" рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЬрд╝рд░реВрд░рдд рд╣реИ рдЫрд╡рд┐ рд╕рдордп (рдЬрдм рдПрдХ рддрддреНрд╡ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рддреЗ рд╣реБрдП, рдкреВрд░реЗ "sqrt рд╕реЗрдЧрдореЗрдВрдЯ" рдкрд░ рдорд┐рдирдЯ / рдЕрдзрд┐рдХрддрдо рдХрд╛ рдкреБрдирд░рд╛рд╡рд░реНрддрди рдХрд░реЗрдВ), рд▓реЗрдХрд┐рди рдЕрдЧрд░ рд╣рдо рдЕрдкрдбреЗрдЯ рдкрд░ рдХреБрдЫ рдкреНрд░рддрд┐рдмрдВрдз рд▓рдЧрд╛рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдПрдХ рдЕрдиреБрдорд╛рди рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗ рдЫрд╡рд┐ ред рдиреНрдпреВрдирддрдо, рдЕрдзрд┐рдХрддрдо / рдЕрдзрд┐рдХрддрдо рдЦреЛрдЬрдиреЗ рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рддреЗ рд╕рдордп, рдХреЗрд╡рд▓ рддрддреНрд╡ рдХреЛ рдХрдо рдХрд░рдиреЗ / рдмрдврд╝рд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдВред
рдиреНрдпреВрдирддрдо рдЕрджреНрдпрддрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдб:
 int decElement(int index, unsigned int delta) //delta -     { A[index] -= delta; sqrtSums[index/len] = min(sqrtSums[index/len], A[index]); } 

рдЗрд╕реА рддрд░рд╣, рдЕрдзрд┐рдХрддрдо рдЕрджреНрдпрддрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП:
 int incElement(int index, unsigned int delta) //delta -     { A[index] += delta; sqrtSums[index/len] = max(sqrtSums[index/len], A[index]); } 

рдпрд╣ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдЖрд░рдПрдордХреНрдпреВ рд╕рдорд╕реНрдпрд╛ рдореЗрдВ, рдХрд╛рд░реНрдп рдХрдо рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ [0]; рдЖрд░] - [0; рдПрд▓ -1], рдпрд╛рдиреА рдЖрдкрдХреЛ рдПрд▓ рд╕реЗ рдЖрд░ рддрдХ рдиреНрдпреВрдирддрдо / рдЕрдзрд┐рдХрддрдо рдХреА рдЧрдгрдирд╛ рдХрд░рдиреА рд╣реЛрдЧреА (рдлрд┐рд░ рд╕реЗ рдЧрд┐рдирддреЗ рд╣реБрдП, "sqrt рд╕реЗрдЧрдореЗрдВрдЯ" рдЬреЛ рдХрд┐ [L; R] рдореЗрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╣реИрдВ, рд╕реЛрдЪреЗрдВ рдХрд┐ рдХреНрдпреЛрдВ рд╡рд┐рд╖рдорддрд╛ рдХрд╛ рд╡реНрдпрд╡рд╣рд╛рд░ рдирд╣реАрдВ рдмрджрд▓реЗрдЧрд╛, рдФрд░ рд╢реБрджреНрдз рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рднреА рд╕реБрдзрд╛рд░ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ ...)ред

рдЬреАрд╕реАрдбреА (рдЧреНрд░реЗрдЯреЗрд╕реНрдЯ рдХреЙрдорди рдбрд┐рд╡рд┐рдЬрд╝рд░) рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо "рдЪрд┐рдк" рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рдкрд╛рдПрдВрдЧреЗ рдЬреЛ рд╣рдордиреЗ рдорд┐рдирдЯ / рдЕрдзрд┐рдХрддрдо рдХреЗ рд▓рд┐рдП рдмрджрд▓ рджрд┐рдпрд╛ рдерд╛ред рдЗрд╕рд▓рд┐рдП, рджреЛрдиреЛрдВ рдСрдкрд░реЗрд╢рди рдХреЗ рд▓рд┐рдП рдЧрдгрдирд╛ рдХреА рдЬрд╛рддреА рд╣реИ рдЫрд╡рд┐ ред
GCD рдХреЗ рд▓рд┐рдП рдХреЛрдб (рдиреНрдпреВрдирддрдо рдФрд░ рдЕрдзрд┐рдХрддрдо рдХреЗ рд▓рд┐рдП, getGCD рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдорд┐рдирдЯ / рдЕрдзрд┐рдХрддрдо рджреНрд╡рд╛рд░рд╛ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛):
 int getGCD(int a, int b) { while(a && b) { if(a < b) b %= a; else a %= b; } return a + b; } int gcdRQ(int l, int r) { int cur_gcd = A[l++]; for(int i = l; i <= r;) if (i % len == 0 && i + len - 1 <= r) { cur_gcd = getGCD(cur_gcd, b[i / len]); i += len; //  "sqrt-" } else cur_gcd = getGCD(cur_gcd, A[i++]); } 


рд╕реВрддреНрд░реЛрдВ рдХрд╛ рдХрд╣рдирд╛ рд╣реИ


рдЗрд╕ рд╕рд╛рдЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ , рдЕрд░реНрдерд╛рддреН ред
рдЪреВрдВрдХрд┐ рдЦрд╛рд░рдХреЛрд╡ рд╡рд┐рдВрдЯрд░ рдХрдВрдкреНрдпреВрдЯрд░ рд╕реНрдХреВрд▓ рдХреЗ рд╡реНрдпрд╛рдЦреНрдпрд╛рди рдиреЗ рд▓реЗрдЦ рдХреЛ рдкреНрд░реЗрд░рд┐рдд рдХрд┐рдпрд╛, рдореИрдВ рд╕рд╛рдЗрдЯ рдХреЛ рдлреЗрдВрдХ рджреВрдВрдЧрд╛, рд╢рд╛рдпрдж рдЬрд▓реНрдж рд╣реА рдЗрд╕ рд╕рд╛рд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡реАрдбрд┐рдпреЛ рд╕рдВрдЧреНрд░рд╣ рдХреЗ рд╕рд╛рде рд╕рдВрдЧреНрд░рд╣ рд╣реЛрдЧрд╛ред

рдЕрднреА рдХреЗ рд▓рд┐рдП, рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдерд╛ред

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


All Articles