class Poly attr_accessor :array, :limit #系数向量,次数界 def initialize(a) @array = [] a.each {|e| @array.push Complex(e, 0)} [url=home.php?mod=space&uid=215071]@limit[/url] = a.size end def exchange #位逆序置换 j = 0 (0...@limit).each do |i| if j > i t = @array[i] @array[i] = @array[j] @array[j] = t end k = @limit j &= ~k while j&(k >>= 1) != 0 #倒着做减法 j |= k end end PI = Math.acos(-1) def fft(idft = false) pi = PI pi = -pi if idft #idft旋转方向反过来 exchange #置换 s = 1 #合并区间的长度 while s < @limit t = 0 while t < @limit #合并区间的开始点 x = pi/s omgn = Complex(Math.cos(x), Math.sin(x)) omg = Complex(1.0, 0.0) (0...s).each do |m| a1 = m+t a2 = m+t+s Complex comm = omg * @array[a2] #蝴蝶操作 @array[a2] = @array[a1] - comm @array[a1] = @array[a1] + comm omg = omg*omgn end t += s<<1 end s <<= 1 end @array.map!{|e| e/@limit} if idft #逆变换 end def mul(o) s = 1 s <<= 1 while s < @limit + o.limit (@limit...s).each {|i| @array[i] = Complex(0.0, 0.0)} (o.limit...s).each {|i| o.array[i] = Complex(0.0, 0.0)} #不足补零 @limit = o.limit = s #修正次数界 fft o.fft (0...s).each do |i| @array[i] *= o.array[i] end fft(true) end #----------------------- def mul_with(poly) x = Poly.new(@array) y = Poly.new(poly.array) x.mul(y) (0...x.limit).each do |i| @array[i] = Integer(x.array[i].real+0.5) #四舍五入... end end end #test #多项式乘法(1+2x)(1+2x+x^2) = (1+4x+5x^2+2x^3) #结果的多项式次数界为3,四项 x = Poly.new([1, 2]) y = Poly.new([1, 2, 1]) x.mul_with y #输出结果的系数 #puts x.array #=> 1 4 5 2 0 0 0 0 (末尾4个0是多余的) puts x.array[0..3]
1.08 KB, 下载次数: 64
内含这个脚本文件
欢迎光临 Project1 (https://rpg.blue/) | Powered by Discuz! X3.1 |