рдлреВрд░рд┐рдпрд░ рд░реВрдкрд╛рдВрддрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рдмрд╣реБрдкрдж рдХрд╛ рдмрд╣реБрдЧреБрдгрдирд╛ рдЖрд╕рд╛рди рд╣реИ

рд╢реБрдн рд╕рдВрдзреНрдпрд╛

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

FFT рдПрдХ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╣реИ рдЬреЛ рд╕рдордп n рдореЗрдВ рдХреБрдЫ n рдмрд┐рдВрджреБрдУрдВ рдкрд░ рдбрд┐рдЧреНрд░реА n = 2 k рдХреЗ рдмрд╣реБрдкрдж рдХреЗ рдорд╛рдиреЛрдВ рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИ ( n (log n ) ("рднреЛрд▓реЗ" рд╡рд┐рдзрд┐ рд╕рдордп O ( n 2 ) рдореЗрдВ рдПрдХ рд╣реА рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ)ред рдЙрд╕реА рд╕рдордп, рдЖрдк рдЙрд▓рдЯрд╛ рдкрд░рд┐рд╡рд░реНрддрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рдЬреЛрдбрд╝, рдШрдЯрд╛рд╡ рдФрд░ рдЧреБрдгрд╛ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдмрд╛рдж рд╕реЗ, рдмрд╣реБрдкрдж (рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЧреБрдгрд╛) рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИ, FFT рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрдХреНрд╕рд░ рдмрд╣реБрдкрдж рдФрд░ рд▓рдВрдмреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде рдЧрдгрдирд╛ рдХреЛ рдЧрддрд┐ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдкрд░рд┐рднрд╛рд╖рд╛рдПрдБ рдФрд░ рдЙрдкрдпреЛрдЧ



рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЖрдЗрдП рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ рдХрд┐ рдПрдХ рдмрд╣реБрдкрдж рдХреНрдпрд╛ рд╣реИ:

P ( x ) = a 0 + x a 1 + x 2 a 2 + x 3 a 3 + ... + x n - 1 a n - 1

рдЬрдЯрд┐рд▓ рд╕рдВрдЦреНрдпрд╛



рдпрджрд┐ рдЖрдк рдЬрдЯрд┐рд▓ рд╕рдВрдЦреНрдпрд╛рдУрдВ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реИрдВ, рддреЛ рдЖрдк рдЗрд╕ рдмрд┐рдВрджреБ рдХреЛ рдЫреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ, рдЕрдиреНрдпрдерд╛, рдпрд╣рд╛рдБ рдПрдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдкрд░рд┐рднрд╛рд╖рд╛ рд╣реИ:

x = a + i b , рдЬрд╣рд╛рдБ рдореИрдВ 2 = - 1

рдпрд╣рд╛рдБ a рдХреЛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ ( Real ) рднрд╛рдЧ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ b рдХрд╛рд▓реНрдкрдирд┐рдХ ( Imaginary ) рднрд╛рдЧ рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдХреЛрдИ рднреА рдЗрди рдирдВрдмрд░реЛрдВ рд╕реЗ рдирдХрд╛рд░рд╛рддреНрдордХ (рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрд┐рд╕реА рднреА) рд╕рдВрдЦреНрдпрд╛рдУрдВ рд╕реЗ рдПрдХ рдЬрдбрд╝ рдирд┐рдХрд╛рд▓ рд╕рдХрддрд╛ рд╣реИ - рдпрд╣ рдмрд╣реБрдкрдж рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ - рдмреАрдЬрдЧрдгрд┐рдд рдХреЗ рдореБрдЦреНрдп рдкреНрд░рдореЗрдп рд╕реЗ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░, рдбрд┐рдЧреНрд░реА рдПрди рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдмрд╣реБрдкрдж рдореЗрдВ рдмрд┐рд▓реНрдХреБрд▓ рдЬрдЯрд┐рд▓ рдЬрдбрд╝реЗрдВ рд╣реЛрддреА рд╣реИрдВ (рдЦрд╛рддреЗ рдХреЛ рдЧреБрдгрд╛ рдХрд░рдирд╛ )ред

рд╡рд┐рдорд╛рди рдкрд░ рдмрд┐рдВрджреБрдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдирдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдирд╛ рднреА рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ:



рдЬрдЯрд┐рд▓ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреА рдПрдХ рдФрд░ рдЙрд▓реНрд▓реЗрдЦрдиреАрдп рд╕рдВрдкрддреНрддрд┐ рдпрд╣ рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЗрдВ x = (cos╬▒ + i sin╬▒) r рдХреЗ рд░реВрдк рдореЗрдВ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ ╬▒ "рд╕рдВрдЦреНрдпрд╛" (рдПрдХ рддрд░реНрдХ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ ) рдХрд╛ рдзреНрд░реБрд╡реАрдп рдХреЛрдг рд╣реИ, рдФрд░ r рд╢реВрдиреНрдп рд╕реЗ рдЗрд╕рдХреА рджреВрд░реА ( рдорд╛рдкрд╛рдВрдХ ) рд╣реИред рдФрд░ рджреЛ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЛ рдЧреБрдгрд╛ рдХрд░рдиреЗ рдкрд░:

a = (cos╬▒ + i cos sin╬▒) r a

b = (cos r + i ╬▓sin () r b

a b = (cos╬▒ + i insin╬▒) (cos i + i ╬▓sin╬▓) r r b

a b = (cos╬▒тЛЕcos╬▓-sin╬▒╬▓sin i + i (sin╬▒╬▓cos╬▓ + cos╬▓тЛЕsin╬▒)) r r b

a b = (cos (╬▒ + ╬▓) + i sin (╬▒ + ()) r r b

рдЙрдирдХреЗ рдореЙрдбреНрдпреВрд▓ рдЧреБрдгрд╛ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рддрд░реНрдХ рдЬреЛрдбрд╝ рджрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред

1 рдХреА рдЬрдЯрд┐рд▓ рдЬрдбрд╝реЗрдВ



рдЕрдм рдЖрдЗрдП рд╕рдордЭрддреЗ рд╣реИрдВ рдХрд┐ 1 рд╕реЗ nth рдбрд┐рдЧреНрд░реА рдХреА рдЬрдЯрд┐рд▓ рдЬрдбрд╝реЗрдВ рдХреИрд╕реА рджрд┐рдЦрддреА рд╣реИрдВред X n = 1 рдХреЛ рджреЗрдВ , рддреЛ рдЗрд╕рдХрд╛ рдореЙрдбреНрдпреВрд▓ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдПрдХрддрд╛ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ, рдФрд░ n xarg x = 2 is k , рдЬрд╣рд╛рдВ k рдПрдХ рдкреВрд░реНрдгрд╛рдВрдХ рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдЕрдкрдиреЗ рдЖрдк рд╕реЗ рдЧреБрдгрд╛ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж (рдЬреЛ рдХрд┐ nth рдкрд╛рд╡рд░ рддрдХ рдмрдврд╝ рд░рд╣реА рд╣реИ), рдЗрд╕рдХрд╛ рддрд░реНрдХ "рдХрдИ" 2 multiple (360 рдбрд┐рдЧреНрд░реА) рд╣реЛ рдЬрд╛рдПрдЧрд╛ред

рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕реВрддреНрд░ рдХреЛ рдпрд╛рдж рдХрд░реЗрдВ, рдпрджрд┐ рддрд░реНрдХ рдФрд░ рдореЙрдбреНрдпреВрд▓ рдЬреНрдЮрд╛рдд рд╣реИрдВ, рддреЛ рд╣рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ:

╬▒ = 2 / x / n , рдЬрд╣рд╛рдВ 0 x

╧Й i = cos╬▒ + i insin╬▒

рдпрд╛рдиреА рдпрджрд┐ рдЖрдк рдбреНрд░рд╛ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдмрд░рд╛рдмрд░ рдЕрдВрддрд░рд╛рд▓ рдкрд░ рд╕рд░реНрдХрд▓ рдкрд░ рдХреЗрд╡рд▓ рдЕрдВрдХ рдорд┐рд▓рддреЗ рд╣реИрдВ:



рдХреГрдкрдпрд╛ рддреАрди рдЪреАрдЬреЛрдВ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ рдЬрд┐рдирдХрд╛ рд╣рдо рд╕рдХреНрд░рд┐рдп рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ (рдЙрдирдХреЗ рдмрд┐рдирд╛, рдХреБрдЫ рднреА рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛):

= a ╧Й b = ╧Й ( a + b ) mod n

╧Й 0 + ╧Й 1 + + 2 + ... + 1 n - 1 = 0

╧Й 0 n / 2 = n 2 n / 2 = 2 4 n / 2 = ... = 1 ( n рдХреЗ рд▓рд┐рдП рднреА)

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

рдЬрдбрд╝реЛрдВ рдХрд╛ рдпреЛрдЧ рд╢реВрдиреНрдп рдХреНрдпреЛрдВ рд╣реИ



рдкреНрд░рдорд╛рдг рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ: ╧Ж = is 0 + + 1 + ... рджреЗрдВред рджреЛрдиреЛрдВ рдкрдХреНрд╖реЛрдВ рдХреЛ ( 1 (! = 1) рд╕реЗ рдЧреБрдгрд╛ рдХрд░реЗрдВред рдХреНрдпреЛрдВрдХрд┐ ╧Й i ╧Й 1 = ╧Й i + 1 , рдлрд┐рд░ ╧Й 1 = ╧Й 1 + ╧Й 2 + ... + + n - 1 + ╧Й 0 ред рд╢рдмреНрджреЛрдВ рдХреЗ рдкреБрдирд░реНрд╡реНрдпрд╡рд╕реНрдерд╛ рд╕реЗ, рдпреЛрдЧ рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП, рдХреНрд░рдорд╢рдГ ╧ЖтЛЕ╧Й = range 1 , ╧Й (= 1 - 1 ) = 0 ред рдХреНрдпреЛрдВрдХрд┐ ╧Й 1 ! = 1, рдлрд┐рд░ ╧Ж = 0 ред

рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ



рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдмрд╣реБрдкрдж рдореЗрдВ рдбрд┐рдЧреНрд░реА n = 2 k рд╣реИ ред рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рд╣рдо рджреЛ рдХреЗ рдирд┐рдХрдЯрддрдо рд╢рдХреНрддрд┐ рдХреЗ рд▓рд┐рдП рдЕрдЧреНрд░рдгреА рдЧреБрдгрд╛рдВрдХ рдХреЛ рд╢реВрдиреНрдп рдХреЗ рд╕рд╛рде рдкреВрд░рдХ рдХрд░рддреЗ рд╣реИрдВред

рдПрдлрдПрдлрдЯреА рдХрд╛ рдореВрд▓ рд╡рд┐рдЪрд╛рд░ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ:

рдХрд░рддреЗ рд╣реИрдВ:

A ( x ) = a 0 + x a 2 + x 2 a 4 + ... + x n / 2 - 1 a n - 2 (рдЧреБрдгрд╛рдВрдХ P )

B ( x ) = 1 + x a 3 + x 2 a 5 + ... + x n / 2 - 1 a n - 1 (рд╡рд┐рд╖рдо рдЧреБрдгрд╛рдВрдХ P )ред

рдлрд┐рд░ P ( x ) = A ( x 2 ) + x x B ( x 2 )ред

рдЕрдм рд╣рдо "рд╡рд┐рднрд╛рдЬрд┐рдд рдФрд░ рдЬреАрддрддреЗ рд╣реИрдВ" рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ: n рдмрд┐рдВрджреБрдУрдВ рдкрд░ P рдХреЗ рдорд╛рдиреЛрдВ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП (, 0 , of 1 , ... ), рд╣рдо A рдФрд░ B рдХреЗ рдорд╛рдиреЛрдВ рдХреА рдЧрдгрдирд╛ n / 2 рдмрд┐рдВрджреБрдУрдВ рдкрд░ рдХрд░рддреЗ рд╣реИрдВ (, 0 , ╧Й 2 , ... ) ред рдЕрдм P рдХрд╛ рдореВрд▓реНрдп (╧Й i ) рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ:

P ( i i ) = A (╧Й 2 i ) + тЛЕ i ╧Й B ( i 2 i )

рдпрджрд┐ рд╣рдо ╬╛ i = den 2 рд╕реЗ рдирд┐рд░реВрдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЬрд┐рди рдмрд┐рдВрджреБрдУрдВ рдкрд░ рд╣рдо рдбрд┐рдЧреНрд░реА n / 2 рдХреЗ рдмрд╣реБрдкрдж рдХреЗ рдорд╛рдиреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ, рд╡рд╣ рд╕реВрддреНрд░ рд░реВрдкрд╛рдВрддрд░рд┐рдд рд╣реЛ рдЬрд╛рдПрдЧрд╛:

P () i ) = A (╬╛ i ) +) i ╬╛ B (╧Й i )

рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреНрд░реЛрдЧреНрд░рд╛рдо рдореЗрдВ рд╕рдВрдЪрд╛рд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдпрд╣ рднреВрд▓рдХрд░ рдХрд┐ рдореИрдВ 0 рд╕реЗ n - 1 рддрдХ рдорд╛рди рд▓реЗрддрд╛ рд╣реВрдВ , рдФрд░ ╬╛ i рдХреЛ рдХреЗрд╡рд▓ 0 рд╕реЗ n / 2 - 1 рддрдХ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдирд┐рд╖реНрдХрд░реНрд╖ - i modulo n / 2 рд▓реЗрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛ред

рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рдордп рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рд╕реВрддреНрд░ T ( n ) = O ( n ) + 2 T ( n / 2 ) рджреНрд╡рд╛рд░рд╛ рд╡реНрдпрдХреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдПрдХ рдХрд╛рдлреА рдкреНрд░рд╕рд┐рджреНрдз рд╕рдВрдмрдВрдз рд╣реИ рдФрд░ рдпрд╣ O ( n nlog 2 n ) рдореЗрдВ рдкреНрд░рдХрдЯ рд╣реЛрддрд╛ рд╣реИ (рд▓рдЧрднрдЧ рдмреЛрд▓рддреЗ рд╣реБрдП, рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреА рдЧрд╣рд░рд╛рдИ 2 рд╕реНрддрд░ n рд▓реЙрдЧ рд╣реЛрддреА рд╣реИ, рдкреНрд░рддреНрдпреЗрдХ рд╕реНрддрд░ рдкрд░ O ( n ) рдСрдкрд░реЗрд╢рди рд╕рднреА рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдХреБрд▓ рдореЗрдВ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ)ред

рдХреБрдЫ рд▓рд┐рдЦреЛ



рдпрд╣рд╛рдБ рдПрдХ рдЕрдХреНрд╖рдо рдкреБрдирд░рд╛рд╡рд░реНрддреА рдПрдлрдПрдлрдЯреА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ:

рдзреАрдореЗ рдзреАрдореЗ
#include <vector> #include <complex> using namespace std; typedef complex<double> cd; // STL-  .   double,     sin  cos typedef vector<cd> vcd; vcd fft(const vcd &as) { //       1 int n = as.size(); // -    ? if (n == 1) return vcd(1, as[0]); vcd w(n); //   for (int i = 0; i < n; i++) { double alpha = 2 * M_PI * i / n; w[i] = cd(cos(alpha), sin(alpha)); } //   A  B vcd A(n / 2), B(n / 2); for (int i = 0; i < n / 2; i++) { A[i] = as[i * 2]; B[i] = as[i * 2 + 1]; } vcd Av = fft(A); vcd Bv = fft(B); vcd res(n); for (int i = 0; i < n; i++) res[i] = Av[i % (n / 2)] + w[i] * Bv[i % (n / 2)]; return res; }
      
      





рдЖрдк I / O рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЕрдкрдиреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рд╢реБрджреНрдзрддрд╛ рдХреЛ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдмрд╣реБрдкрдж рдкреА ( x ) = 4 + 3 x + 2 x 2 + x 3 + 0 4 x 4 + 0 + x 5 + 0 6 x 6 + 0 x 7 рдорд╛рди рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИрдВ:

рдкреА ( рдбрдмреНрд▓реНрдпреВ 0 ) = ( 1 0. 0 0 0 , 0. 0 0 0 )

рдкреА ( рдбрдмреНрд▓реНрдпреВ 1 ) = ( 5. 4 1 4 , 4. 8 2 8 )

P ( w 2 ) = ( 2. 0 0 0 , 2. 0 0 0 )

рдкреА ( рдбрдмреНрд▓реНрдпреВ 3 ) = ( 2. 5 8 6 , 0. 8 2 8 )

P ( w 4 ) = ( 2. 0 0 0 , 0. 0 0 0 )

P ( w 5 ) = ( 2. 5 8 6 , - 0. 8 2 8 )

рдкреА ( рдбрдмреНрд▓реНрдпреВ 6 ) = ( 2. 0 0 0 , - 2. 0 0 0 )

рдкреА ( рдбрдмреНрд▓реНрдпреВ 7 ) = ( 5. 4 1 4 , - 4. 8 2 8 )

рдпрджрд┐ рд╣рд╛рдВ, рддреЛ рдЖрдк рдмрдбрд╝реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдкрд░ рдкреБрдирд░рд╛рд╡рд░реНрддреА рдФрд░ рднреЛрд▓реА рд╡рд┐рдзрд┐ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдбрд┐рдЧреНрд░реА 2 12 рдХреА рдПрдХ рдмрд╣реБрдкрдж рдкрд░ , рдпрд╣ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди 62 рдПрдордПрд╕ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдФрд░ 1800 рдПрдордПрд╕ рдХреЗ рд▓рд┐рдП рднреЛрд▓реА рдПрдХред рдЕрдВрддрд░ рд╕реНрдкрд╖реНрдЯ рд╣реИред

рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛



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



рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЖрдк рдПрдХ рд╕рд░рдгреА рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕реЗ рд╢реБрд░реВ рдореЗрдВ рдорд╛рдиреЛрдВ рдХреЗ рд╕рд╛рде рднрд░реЗрдВ fft ( 0 ), fft ( рдПрдХ 4 ), fft ( a 2 ), .... рдпрд╣ рд╕рдордЭрдирд╛ рдЖрд╕рд╛рди рд╣реИ рдХрд┐ рд╕рдВрдЦреНрдпрд╛рдПрдБ I рдПрдХ рд╕рдВрдЦреНрдпрд╛ рд╣реИрдВ " 0 , 1 , 2 , 3 , ... " рдЬреЛ рдХрд┐ рдмрд╛рдЗрдирд░реА рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдореЗрдВ "рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд" рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, 1 1 0 = 0 0 1 2 , 4 1 0 = 1 0 2 2 рдпрд╛ 6 = 1 1 0 2 , 3 = 0 1 1 2 ред рдЖрдк рдЗрд╕реЗ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╕рдордЭ рд╕рдХрддреЗ рд╣реИрдВ: рдЬрдм рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреЗ рдирд┐рдЪрд▓реЗ рд╕реНрддрд░ рдкрд░ рдЙрддрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдПрдХ рдФрд░ рдХрдо рдмрд┐рдЯ (рдЕрдВрдд рд╕реЗ) рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдФрд░ "рд╕рд╛рдорд╛рдиреНрдп" рдирдВрдмрд░рд┐рдВрдЧ рдХреЗ рд╕рд╛рде, рдмрд┐рдЯ рдХреЛ рд╢реБрд░реБрдЖрдд рд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдЖрдкрдХреЛ рд╕рдВрдЦреНрдпрд╛ рдХрд╛ "рд╡рд┐рд╕реНрддрд╛рд░" рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЗрд╕реЗ O ( n nlog 2 n ) рдХреЗ рд▓рд┐рдП "рдорд╛рдереЗ" рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдпрд╛ рдЗрд╕реЗ рдирд┐рдореНрди рдПрд▓реНрдЧреЛрд░рд┐рдердо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ O ( n ) рдХреЗ рд▓рд┐рдП рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

  1. 0 рд╕реЗ n - 1 рддрдХ рдПрдХ рдЪрдХреНрд░ рдЪрд▓рд╛рдПрдВ
  2. рд╣рдо рд╕реНрдЯреЛрд░ рдХрд░реЗрдВрдЧреЗ рдФрд░ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдирдВрдмрд░ рдХреА рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЗрдХрд╛рдИ рдмрд┐рдЯ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдкреБрди: рд▓рд┐рдЦреЗрдВрдЧреЗред рдпрд╣ рдХреЗрд╡рд▓ рддрднреА рдмрджрд▓рддрд╛ рд╣реИ рдЬрдм рд╡рд░реНрддрдорд╛рди рд╕рдВрдЦреНрдпрд╛ рджреЛ рдХреА рд╢рдХреНрддрд┐ рд╣реЛрддреА рд╣реИ: 1 рд╕реЗ рдмрдврд╝ рдЬрд╛рддреА рд╣реИред
  3. рдЬрдм рд╣рдо рдХрд┐рд╕реА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдЯ рдХреЛ рдЬрд╛рдирддреЗ рд╣реИрдВ, рддреЛ рдкреВрд░реА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдлрд╝реНрд▓рд┐рдк рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реИ: "рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдЯ (XOR) рдХреЛ рдХрд╛рдЯреЗрдВ", рд╢реЗрд╖ (рдкрд╣рд▓реЗ рд╕реЗ рдЧрдгрдирд╛ рдХреА рдЧрдИ рдореВрд▓реНрдп) рдлреНрд▓рд┐рдк рдХрд░реЗрдВ рдФрд░ рдПрдХ "рдХрдЯ рдСрдл" рдЗрдХрд╛рдИ рдЬреЛрдбрд╝реЗрдВ


рдЕрдм рд╣рдо рдПрдХ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рд╕рд╛рде рдЖрдПрдВрдЧреЗ рдЬреЛ рд╣рдореЗрдВ "рдЪрд░рдг" рд╕реЗ рдПрдХ рдХрджрдо рдКрдВрдЪрд╛ рдкрд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рд╣рдо рдПрдХ рдЪрд░рдг рдореЗрдВ рдкрд┐рдЫрд▓реЗ рдЪрд░рдг рд╕реЗ рд╕рднреА рдорд╛рди рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░реЗрдВрдЧреЗред рдЬреИрд╕рд╛ рдХрд┐ рдЖрдВрдХрдбрд╝реЗ рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдкрд╣рд▓реЗ рдХреЗ = 1 рдХреЗ рд╕рд╛рде рдХрд╢реНрдореАрд░ рдХреЗ рдмреНрд▓реЙрдХ рдореЗрдВ рдбреЗрдЯрд╛ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдФрд░ рдлрд┐рд░ рдпрд╣ рдкреНрд░рддреНрдпреЗрдХ рдЪрд░рдг рдХреЗ рд╕рд╛рде рджреЛрдЧреБрдирд╛ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рд╣рдо рд▓рдВрдмрд╛рдИ k рдХреЗ рджреЛ рдЦрдВрдбреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдкрд░ рд▓рдВрдмрд╛рдИ 2 k рдХрд╛ рдПрдХ рдЦрдВрдб рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред рдЖрдЗрдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦреЗрдВ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдкреБрдирд░рд╛рд╡рд░реНрддреА рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рд▓реЗрдЦ рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ рд╕реВрддреНрд░ рдХреЛ рдпрд╛рдж рдХрд░реЗрдВ рдФрд░ рджреЛрд╣рд░рд╛рдПрдВ:



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

рдмреНрд▓реЙрдХ рд╡рд┐рд▓рдп
 void fft_merge(const vcd &src, vcd &dest, int start, int len) { int p1 = start; //     int en1 = start + len; //    int p2 = start + len; //     int en2 = star + len * 2; //    int pdest = start; //      int nlen = len * 2; //    for (int i = 0; i < nlen; i++) { double alpha = 2 * M_PI * i / nlen; cd w = cd(cos(alpha), sin(alpha)); //   dest[pdest] = src[p1] + w * src[p2]; if (++p1 >= en1) p1 = start; if (++p2 >= en2) p2 = start + len; } }
      
      





рдФрд░ рдореБрдЦреНрдп рд░реВрдкрд╛рдВрддрд░рдг рдкреНрд░рдХреНрд░рд┐рдпрд╛:

 vcd fft(const vcd &as) { int n = as.size(); int k = 0; //  n   while ((1 << k) < n) k++; vi rev(n); rev[0] = 0; int high1 = -1; for (int i = 1; i < n; i++) { if ((i & (i - 1)) == 0) //    .  i  ,  i-1     . high1++; rev[i] = rev[i ^ (1 << high1)]; //   rev[i] |= (1 << (k - high1 - 1)); //    } vcd cur(n); for (int i = 0; i < n; i++) cur[i] = as[rev[i]]; for (int len = 1; len < n; len <<= 1) { vcd ncur(n); for (int i = 0; i < n; i += len * 2) fft_merge(cur, ncur, i, len); cur.swap(ncur); } return cur; }
      
      





рдЕрдиреБрдХреВрд▓рди



рдбрд┐рдЧреНрд░реА 2 1 6 рдХреЗ рдПрдХ рдмрд╣реБрдкрдж рдкрд░ , рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ 640 рдПрдордПрд╕ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ , рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреЗ рдмрд┐рдирд╛ - 500. рдПрдХ рд╕реБрдзрд╛рд░ рд╣реИ, рд▓реЗрдХрд┐рди рдХрд╛рд░реНрдпрдХреНрд░рдо рдФрд░ рднреА рддреЗрдЬреА рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╣рдо рдЙрд╕ рд╕рдВрдкрддреНрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ ╧Й i = -╧Й i + n / 2 рд╣реИ ред рдЗрд╕рд▓рд┐рдП, рд╣рдо рд░реВрдЯ рдХреЛ рджреЛ рдмрд╛рд░ рдирд╣реАрдВ рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ i the j - рдЬрдЯрд┐рд▓ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рд╕рд╛рдЗрди, рдХреЛрд╕рд╛рдЗрди рдФрд░ рдЧреБрдгрд╛ рдмрд╣реБрдд рдорд╣рдВрдЧрд╛ рд╕рдВрдЪрд╛рд▓рди рд╣реИред

fft_merge ()
 for (int i = 0; i < len; i++) { double alpha = 2 * M_PI * i / nlen; cd w = cd(cos(alpha), sin(alpha)); //   cd val = w * src[p2]; dest[pdest] = src[p1] + val; dest[pdest + len] = src[p1] - val; pdest++; if (++p1 >= en1) p1 = start; if (++p2 >= en2) p2 = start + len; }
      
      





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

fft_merge ()
 int rstep = roots.size() / nlen; //      for (int i = 0; i < len; i++) { cd w = roots[i * rstep]; cd val = w * src[p2];
      
      





рдПрдлрдПрдлрдЯреА ()
 roots = vcd(n); for (int i = 0; i < n; i++) { double alpha = 2 * M_PI * i / n; roots[i] = cd(cos(alpha), sin(alpha)); }
      
      





рдЕрдм рдЧрддрд┐ 78 рдПрдордПрд╕ рд╣реИред рдкрд╣рд▓реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рддреБрд▓рдирд╛ рдореЗрдВ 8 рдЧреБрдирд╛ рдЕрдиреБрдХреВрд▓рди!

рдХреЛрдб рдЕрдиреБрдХреВрд▓рди



рд╡рд░реНрддрдорд╛рди рдореЗрдВ, рд╕рднреА рд░реВрдкрд╛рдВрддрд░рдг рдХреЛрдб рдореЗрдВ рд▓рдЧрднрдЧ 55 рд▓рд╛рдЗрдиреЗрдВ рд╣реИрдВред рд╕реМ рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдХрд╛рдлреА рд╣реИ - рдпрд╣ рдЫреЛрдЯрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, fft_merge рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рдЪрд░ рдФрд░ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рдПрдХ рд╕рдореВрд╣ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдПрдВ :

 void fft_merge(const vcd &src, vcd &dest, int start, int len) { int p1 = start; //int en1 = start + len; //  , .   int p2 = start + len; //int en2 = start + len * 2; //  int pdest = start; //int nlen = len * 2; //      //int rstep = roots.size() / nlen; int rstep = roots.size() / (len * 2); for (int i = 0; i < len; i++) { //cd w = roots[i * rstep]; //       //cd val = w * src[p2]; cd val = roots[i * rstep] * src[p2]; dest[pdest] = src[p1] + val; dest[pdest + len] = src[p1] - val; pdest++, p1++, p2++; //if (++p1 >= en1) p1 = start; //         2len,    len,     //if (++p2 >= en2) p2 = start + len; //  } }
      
      





рдЕрдм рдЖрдк fft_merge рд╕реЗ рд▓реВрдк рдХреЛ рдореБрдЦреНрдп рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдЖрдк P2 рдХреЛ рднреА рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ P2 = p1 + len - рдЗрд╕рдиреЗ рдореБрдЭреЗ рдПрдХ рдЫреЛрдЯрд╛ рд╕рдордп рднреА рджрд┐рдпрд╛ рд╣реИред рдЬреЛ рдХрд┐ рдЙрддреНрд╕реБрдХ рд╣реИ, рдЕрдЧрд░ рдореИрдВ p1 = pdest рдХреЛ рд╣рдЯрд╛ рджреЗрддрд╛ рд╣реВрдВ, рддреЛ рдореИрдВ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рд╕рдордп рд▓рд╛рдн рдХреЛ рдорд╛рд░ рджреЗрддрд╛ рд╣реВрдВ) :

рдПрдлрдПрдлрдЯреА ()
 for (int len = 1; len < n; len <<= 1) { vcd ncur(n); int rstep = roots.size() / (len * 2); for (int pdest = 0; pdest < n;) { int p1 = pdest; for (int i = 0; i < len; i++) { cd val = roots[i * rstep] * cur[p1 + len]; ncur[pdest] = cur[p1] + val; ncur[pdest + len] = cur[p1] - val; pdest++, p1++; } pdest += len; } cur.swap(ncur); }
      
      





рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд░реВрдкрд╛рдВрддрд░рдг рд╕реНрд╡рдпрдВ рдХреЛ рдЗрддрдирд╛ рдЕрдзрд┐рдХ рдирд╣реАрдВ рд▓реЗрддрд╛ рд╣реИ - 17 рд▓рд╛рдЗрдиреЗрдВред рдмрд╛рдХреА рд╕рдм рдХреБрдЫ - рдЬрдбрд╝реЛрдВ рдХреА рдкреВрд░реНрд╡-рдЧрдгрдирд╛ рдФрд░ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХрд╛ рдЙрд▓рдЯрд╛ред рдпрджрд┐ рдЖрдк рдХрд╛рдо рдХреЗ рд╕рдордп ( O ( n )log 2 n ) O ) ( n ) рдХреЗ рдмрджрд▓реЗ рдХреЛрдб рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИрдВ, рддреЛ рдЖрдк рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЫрд╣ рдХреЗ рд╕рд╛рде рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рдкреНрд░рд╕рд╛рд░ рдХреА 13 рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ:

Fft рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ ()
 vcd cur(n); for (int i = 0; i < n; i++) { int ri = 0; for (int i2 = 0; i2 < k; i2++) //       ri = (ri << 1) | !!(i & (1 << i2)); //      cur[i] = as[ri]; }
      
      





рдирддреАрдЬрддрди, рдХреЛрдб рдЕрдм рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

 vcd fft(const vcd &as) { int n = as.size(); int k = 0; //  n   while ((1 << k) < n) k++; vector<int> rev(n); rev[0] = 0; int high1 = -1; for (int i = 1; i < n; i++) { if ((i & (i - 1)) == 0) //    .  i  ,  i-1     . high1++; rev[i] = rev[i ^ (1 << high1)]; //   rev[i] |= (1 << (k - high1 - 1)); //    } vcd roots(n); for (int i = 0; i < n; i++) { double alpha = 2 * M_PI * i / n; roots[i] = cd(cos(alpha), sin(alpha)); } vcd cur(n); for (int i = 0; i < n; i++) cur[i] = as[rev[i]]; for (int len = 1; len < n; len <<= 1) { vcd ncur(n); int rstep = roots.size() / (len * 2); for (int pdest = 0; pdest < n;) { int p1 = pdest; for (int i = 0; i < len; i++) { cd val = roots[i * rstep] * cur[p1 + len]; ncur[pdest] = cur[p1] + val; ncur[pdest + len] = cur[p1] - val; pdest++, p1++; } pdest += len; } cur.swap(ncur); } return cur; }
      
      





рдЙрд▓рдЯрд╛ рдкрд░рд┐рд╡рд░реНрддрди



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

рдпрд╣рд╛рдВ рдХреЛрдб рдмреЗрд╣рдж рд╕рд░рд▓ рд╣реИ - рд╕рдм рдХреБрдЫ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд▓рд┐рдЦрд╛ рд╣реБрдЖ рд╣реИред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдЗрд╕реЗ рд╕рдВрднрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВред

рд╕рдмреВрдд



рдЖрдЗрдП рд╣рдо рдЧреБрдгрд╛рдВрдХ v ( i ) рдХреЗ рд╕рд╛рде рдмрд╣реБрдкрдж P ( x ) рдХреЗ рд╡реНрдпреБрддреНрдХреНрд░рдо рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рд▓рд╛рдЧреВ рдХрд░реЗрдВ (рдореВрд▓ рдмрд╣реБрдкрдж рдореЗрдВ рдЧреБрдгрд╛рдВрдХ i рдерд╛ ):

v i = a 0 + ╧Й i a 1 + a 2 i a 2 + a 3 i a + ...

рд░реВрдкрд╛рдВрддрд░рдг рдХреЗ рдкрд░рд┐рдгрд╛рдо рдкрд░ рдирдЬрд░ рдбрд╛рд▓рддреЗ рд╣реИрдВ:

b i = v 0 + ╧Й i v 1 + v 2 i v 2 + v 3 i v 3 + ...

рд╣рдо v j рдХреЗ рдорд╛рдиреЛрдВ рдХреЛ рдмрджрд▓рддреЗ рд╣реИрдВ (рдпрд╛рдж рд░рдЦреЗрдВ рдХрд┐ ╧Й ╧Й b = + a + b m o d n :



рдЕрдм рдПрдХ рдЙрд▓реНрд▓реЗрдЦрдиреАрдп рддрдереНрдп рд╕рд┐рджреНрдз рдХрд░рддреЗ рд╣реИрдВ: x prove 0 , ╧Й 0 + ╧Й x + x 2 x + ... + 1 ( n - 1 ) x = 0 рдХреЗ рд▓рд┐рдП ред

рдпрд╣ рдЗрд╕ рддрдереНрдп рдХреЗ рд╕рдорд╛рди рд╕рд┐рджреНрдз рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдЬрдбрд╝реЛрдВ рдХрд╛ рдпреЛрдЧ рд╢реВрдиреНрдп рд╣реИ: рд╣рдо similar рдпреЛрдЧ рд╕реЗ рдирд┐рд░реВрдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рджреЛрдиреЛрдВ рдкрдХреНрд╖реЛрдВ рдХреЛ sides x рд╕реЗ рдЧреБрдгрд╛ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рд╣реБрдЖред

рдЕрдм рдЗрд╕ рддрдереНрдп рдХреЛ b i рдХреЗ рдорд╛рди рдХреА рдЧрдгрдирд╛ рдкрд░ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ n - i рдХреЛ рдЫреЛрдбрд╝рдХрд░ рд╕рднреА рд▓рд╛рдЗрдиреЗрдВ рд╢реВрдиреНрдп рдкрд░ рд░реАрд╕реЗрдЯ рд╣реЛ рдЬрд╛рдПрдВрдЧреАред



рдЗрд╕ рддрд░рд╣ рд╕реЗ:



b i = a n - i тЛЕ (= 0 + - 0 + + 0 + ╧Й 0 + ... )



b i = a n - i - n



рдЬрд┐рд╕реЗ рд╕рд┐рджреНрдз рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛ред

рдЖрд╡реЗрджрди



рдЖрдо рддреМрд░ рдкрд░ рдмреЛрд▓рддреЗ рд╣реБрдП, рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд▓реЗрдЦ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдЖрд╡реЗрджрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛ рдмрд╛рдд рдХреА рдереАред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдЕрдм рдмрд╣реБрдкрдж рдХрд╛ рдЧреБрдгрди рдирд┐рдореНрди рдкреНрд░рдХрд╛рд░ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

рдмрд╣реБрдкрдж рдХрд╛ рддреЗрдЬ рдЧреБрдгрд╛
 vcd a, b; //  //   vcd a_vals = fft(a); vcd b_vals = fft(b); vcd c_vals(a_vals.size()); for (int i = 0; i < a_vals.size(); i++) c_vals[i] = a_vals[i] * b_vals[i]; vcd c = fft_rev(c_vals); //  
      
      





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

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

рдФрд░ рдЕрдВрдд рдореЗрдВ, рдЬреЛ рдХрд╛рд░реНрдп рдореИрдВ рдЕрдЧрд▓реА рдкреЛрд╕реНрдЯ рдореЗрдВ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реВрдВрдЧрд╛: рдЖрдкрдХреЗ рдкрд╛рд╕ рдЕрдХреНрд╖рд░ A, T, G, C. рд╕реЗ рдПрдХ рд╣реА рд▓рдВрдмрд╛рдИ рдХреЗ рдХреНрд░рдо 1 0 5 рдХреА рджреЛ рдкрдВрдХреНрддрд┐рдпрд╛рдБ рд╣реИрдВред рдЗрдирдореЗрдВ рд╕реЗ рдХрд┐рд╕реА рдПрдХ рдкрдВрдХреНрддрд┐ рдХреА рдЪрдХреНрд░реАрдп рдкрд╛рд░реА рдЦреЛрдЬрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рддрд╛рдХрд┐ рд╡рд░реНрдгреЛрдВ рдХреА рдЕрдзрд┐рдХрддрдо рд╕рдВрдЦреНрдпрд╛ рдореЗрд▓ рдЦрд╛рдПред рдЬрд╛рд╣рд┐рд░ рд╣реИ O ( n 2 ) рдХреЗ рд▓рд┐рдП рдПрдХ рднреЛрд▓реА рд╕рдорд╛рдзрд╛рди, рд▓реЗрдХрд┐рди FFT рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рд╕рдорд╛рдзрд╛рди рд╣реИред

рд╕реМрднрд╛рдЧреНрдп рд╣реИ



UPD: рдореИрдВрдиреЗ рдкрд╛рд╕реНрдЯрдмрд┐рди рдкрд░ рдкреВрд░рд╛ рдХреЛрдб рдкреЛрд╕реНрдЯ рдХрд┐рдпрд╛ рд╣реИ



All Articles