关于fft的一点总结

好吧,其实我并没有深入运用fft,只会优化卷积

听说fft经常和生成函数结合在一起………………oi真是迅猛发展,我真是与时代脱节了……

关于fft的学习推荐直接去看算法导论,写得非常清楚

主要弄懂n次单位根的相关性质定理(消去定理,折半定理)即可,当然也可以直接背代码……

bzoj2179

模板题,fft可以优化高精度乘法

顺便说一句,pascal可以定义operator,但跑得慢

这题我跑了10s……

  1 uses math;
  2 type point=record
  3        x,y:double;
  4      end;
  5      arr=array[0..150010] of point;
  6
  7 var a,b,c:arr;
  8     d,r:array[0..150010] of longint;
  9     i,n,m,l:longint;
 10     s:ansistring;
 11
 12 operator +(a,b:point)c:point;
 13   begin
 14     c.x:=a.x+b.x;
 15     c.y:=a.y+b.y;
 16   end;
 17
 18 operator -(a,b:point)c:point;
 19   begin
 20     c.x:=a.x-b.x;
 21     c.y:=a.y-b.y;
 22   end;
 23
 24 operator *(a,b:point)c:point;
 25   begin
 26     c.x:=a.x*b.x-a.y*b.y;
 27     c.y:=a.x*b.y+a.y*b.x;
 28   end;
 29
 30 procedure fft(var a:arr; ty:longint);
 31   var i,j,s,k:longint;
 32       w,p,u,v:point;
 33   begin
 34     for i:=0 to n-1 do
 35       if i<r[i] then
 36       begin
 37         w:=a[r[i]];
 38         a[r[i]]:=a[i];
 39         a[i]:=w;
 40       end;
 41     i:=1;
 42     while i<n do
 43     begin
 44       p.x:=cos(pi/i);
 45       p.y:=ty*sin(pi/i);
 46       s:=i shl 1;
 47       j:=0;
 48       while j<n do
 49       begin
 50         w.x:=1; w.y:=0;
 51         k:=0;
 52         while k<i do
 53         begin
 54           u:=a[j+k];
 55           v:=w*a[j+k+i];
 56           a[j+k]:=u+v;
 57           a[j+k+i]:=u-v;
 58           w:=w*p;
 59           inc(k);
 60         end;
 61         inc(j,s);
 62       end;
 63       i:=i shl 1;
 64     end;
 65   end;
 66
 67 begin
 68   readln(n);
 69   readln(s);
 70   for i:=0 to n-1 do
 71     a[n-1-i].x:=ord(s[i+1])-48;
 72   readln(s);
 73   for i:=0 to n-1 do
 74     b[n-1-i].x:=ord(s[i+1])-48;
 75   dec(n);
 76   m:=2*n;
 77   n:=1;
 78   l:=0;
 79   while n<=m do
 80   begin
 81     n:=n shl 1;
 82     inc(l);
 83   end;
 84   for i:=0 to n-1 do
 85     r[i]:=(r[i shr 1] shr 1) or ((i and 1) shl (l-1));
 86   fft(a,1); fft(b,1);
 87   for i:=0 to n-1 do
 88     c[i]:=a[i]*b[i];
 89   fft(c,-1);
 90   i:=0;
 91   while i<=m do
 92   begin
 93     d[i]:=d[i]+trunc(round(c[i].x/n));
 94     if d[i]>=10 then
 95     begin
 96       d[i+1]:=d[i+1]+d[i] div 10;
 97       d[i]:=d[i] mod 10;
 98     end;
 99     if d[m+1]>0 then inc(m);
100     inc(i);
101   end;
102   for i:=m downto 0 do
103     write(d[i]);
104   writeln;
105 end.

bzoj2194

模板题,倒过来就变成卷积了

不用operator就跑的快多了

 1 type point=record
 2        x,y:double;
 3      end;
 4      arr=array[0..300010] of point;
 5
 6 var a,b,c:arr;
 7     r:array[0..300010] of longint;
 8     h,i,n,l,m:longint;
 9
10 procedure fft(var a:arr; ty:longint);
11   var i,j,k,s:longint;
12       u,v,p,w:point;
13   begin
14     for i:=0 to n-1 do
15       if i<r[i] then
16       begin
17         w:=a[r[i]];
18         a[r[i]]:=a[i];
19         a[i]:=w;
20       end;
21
22     i:=1;
23     while i<n do
24     begin
25       p.x:=cos(pi/i);
26       p.y:=ty*sin(pi/i);
27       s:=i shl 1;
28       j:=0;
29       while j<n do
30       begin
31         w.x:=1;
32         w.y:=0;
33         for k:=0 to i-1 do
34         begin
35           u:=a[j+k];
36           v.x:=w.x*a[j+k+i].x-w.y*a[j+k+i].y;
37           v.y:=w.x*a[j+k+i].y+w.y*a[j+k+i].x;
38           a[j+k].x:=u.x+v.x;
39           a[j+k].y:=u.y+v.y;
40           a[j+k+i].x:=u.x-v.x;
41           a[j+k+i].y:=u.y-v.y;
42           u:=w;
43           w.x:=u.x*p.x-u.y*p.y;
44           w.y:=u.x*p.y+u.y*p.x;
45         end;
46         inc(j,s);
47       end;
48       i:=i shl 1;
49     end;
50   end;
51
52
53 begin
54   readln(n);
55   h:=n;
56   for i:=0 to n-1 do
57     readln(a[i].x,b[n-1-i].x);
58   m:=2*n-2;
59   n:=1;
60   while n<=m do
61   begin
62     n:=n*2;
63     inc(l);
64   end;
65   for i:=0 to n-1 do
66     r[i]:=(r[i shr 1] shr 1) or ((i and 1) shl (l-1));
67   fft(a,1);
68   fft(b,1);
69   for i:=0 to n-1 do
70   begin
71     c[i].x:=a[i].x*b[i].x-a[i].y*b[i].y;
72     c[i].y:=a[i].x*b[i].y+a[i].y*b[i].x;
73   end;
74   fft(c,-1);
75   for i:=h-1 to m do
76     writeln(round(c[i].x/n));
77
78 end.

bzoj3527

给一下题面吧,, 令 Ei=Fi/qi,求Ei

带进去稍微弄弄就是卷积啊……

  1 type point=record
  2        x,y:extended;
  3      end;
  4      arr=array[0..300010] of point;
  5
  6 var a,b,c:arr;
  7     ans,d:array[0..300010] of extended;
  8     r:array[0..300010] of longint;
  9     i,n,m,l:longint;
 10
 11 procedure fft(var a:arr; ty:longint);
 12   var i,j,k,s:longint;
 13       w,p,u,v:point;
 14   begin
 15     for i:=0 to n-1 do
 16       if i<r[i] then
 17       begin
 18         w:=a[r[i]];
 19         a[r[i]]:=a[i];
 20         a[i]:=w;
 21       end;
 22
 23     i:=1;
 24     while i<n do
 25     begin
 26       p.x:=cos(pi/i);
 27       p.y:=ty*sin(pi/i);
 28       s:=i shl 1;
 29       j:=0;
 30       while j<n do
 31       begin
 32         w.x:=1;
 33         w.y:=0;
 34         for k:=0 to i-1 do
 35         begin
 36           u:=a[j+k];
 37           v.x:=w.x*a[j+k+i].x-w.y*a[j+k+i].y;
 38           v.y:=w.x*a[j+k+i].y+w.y*a[j+k+i].x;
 39           a[j+k].x:=u.x+v.x;
 40           a[j+k].y:=u.y+v.y;
 41           a[j+k+i].x:=u.x-v.x;
 42           a[j+k+i].y:=u.y-v.y;
 43           u:=w;
 44           w.x:=u.x*p.x-u.y*p.y;
 45           w.y:=u.x*p.y+u.y*p.x;
 46         end;
 47         inc(j,s);
 48       end;
 49       i:=i shl 1;
 50     end;
 51     if ty=-1 then
 52     begin
 53       for i:=0 to n-1 do
 54         a[i].x:=a[i].x/extended(n);
 55      end;
 56   end;
 57
 58 begin
 59   readln(n);
 60   m:=n;
 61   n:=1;
 62   while n<=2*(m-1) do
 63   begin
 64     n:=n shl 1;
 65     inc(l);
 66   end;
 67   for i:=0 to n-1 do
 68     r[i]:=(r[i shr 1] shr 1) or ((i and 1) shl (l-1));
 69   for i:=0 to m-1 do
 70     readln(d[i]);
 71   for i:=0 to m-1 do
 72   begin
 73     a[i].x:=d[i];
 74     if i<>0 then b[i].x:=1/i/i;
 75   end;
 76   fft(a,1); fft(b,1);
 77   for i:=0 to n-1 do
 78   begin
 79     c[i].x:=a[i].x*b[i].x-a[i].y*b[i].y;
 80     c[i].y:=a[i].x*b[i].y+a[i].y*b[i].x;
 81   end;
 82   fft(c,-1);
 83   for i:=0 to m-1 do
 84     ans[i]:=c[i].x;
 85
 86   for i:=0 to n-1 do
 87   begin
 88     a[i].x:=0;
 89     a[i].y:=0;
 90     if i<m then a[i].x:=d[m-1-i];
 91   end;
 92   fft(a,1);
 93   for i:=0 to n-1 do
 94   begin
 95     c[i].x:=a[i].x*b[i].x-a[i].y*b[i].y;
 96     c[i].y:=a[i].x*b[i].y+a[i].y*b[i].x;
 97   end;
 98   fft(c,-1);
 99   for i:=0 to m-1 do
100   begin
101     ans[i]:=ans[i]-c[m-i-1].x;
102     writeln(ans[i]:0:3);
103   end;
104 end.

bzoj3160

好题,首先合法方案=不连续间隔相等的回文-连续的回文

连续回文的方案显然可以manacher搞出来

连续的呢?考虑穷举中心点,我们只要快算计算中间点两边的相等间隔字符相等的对数s

则此中心点贡献的方案数即为2^s-1

设中心点为k,则s=sigama([a(i)=a(k-i)]) 这里k代表的是manacher翻倍后的下标,i为原串的下标

考虑字符只有a,b两种,我们只要分别统计即可

当统计a时,把a标为1,b标为0,则[a(i)=a(k-i)]=a(i)*a(k-i) 卷积就出现了,fft搞搞即可

注意inline可以加快operator的速度,但要慎用,有时候会出错

  1 uses math;
  2 const mo=1000000007;
  3 type point=record
  4        x,y:double;
  5      end;
  6      arr=array[0..300010] of point;
  7
  8 var a,b:arr;
  9     p,d,r:array[0..300010] of longint;
 10     c:array[0..300010] of char;
 11     s:ansistring;
 12     x,n,l,len,i,ans:longint;
 13
 14 operator +(a,b:point)c:point;inline;
 15   begin
 16     c.x:=a.x+b.x;
 17     c.y:=a.y+b.y;
 18   end;
 19
 20 operator -(a,b:point)c:point;inline;
 21   begin
 22     c.x:=a.x-b.x;
 23     c.y:=a.y-b.y;
 24   end;
 25
 26 operator *(a,b:point)c:point;inline;
 27   begin
 28     c.x:=a.x*b.x-a.y*b.y;
 29     c.y:=a.x*b.y+a.y*b.x;
 30   end;
 31
 32 function min(a,b:longint):longint;
 33   begin
 34     if a>b then exit(b) else exit(a);
 35   end;
 36
 37 function manacher:longint;
 38   var w,t,i,right,k:longint;
 39   begin
 40     c[0]:=‘$‘;
 41     t:=0;
 42     for i:=1 to len do
 43     begin
 44       inc(t); c[t]:=‘#‘;
 45       inc(t); c[t]:=s[i];
 46     end;
 47     c[t+1]:=‘#‘;
 48     right:=0; k:=0;
 49     w:=0;
 50     for i:=1 to t do
 51     begin
 52       if right>i then p[i]:=min(p[2*k-i],right-i)
 53       else p[i]:=1;
 54       while c[i+p[i]]=c[i-p[i]] do inc(p[i]);
 55       w:=(w+p[i] div 2) mod mo;
 56       if p[i]+i>right then
 57       begin
 58         right:=p[i]+i;
 59         k:=i;
 60       end;
 61     end;
 62     exit(w);
 63   end;
 64
 65 procedure fft(var a:arr; ty:longint);
 66   var i,j,k,s:longint;
 67       w,p,u,v:point;
 68   begin
 69     for i:=0 to n-1 do
 70       if i<r[i] then
 71       begin
 72         w:=a[r[i]];
 73         a[r[i]]:=a[i];
 74         a[i]:=w;
 75       end;
 76     i:=1;
 77     while i<n do
 78     begin
 79       p.x:=cos(pi/i);
 80       p.y:=ty*sin(pi/i);
 81       s:=i shl 1;
 82       j:=0;
 83       while j<n do
 84       begin
 85         w.x:=1; w.y:=0;
 86         for k:=0 to i-1 do
 87         begin
 88           u:=a[j+k];
 89           v:=w*a[j+k+i];
 90           a[j+k]:=u+v;
 91           a[j+k+i]:=u-v;
 92           w:=w*p;
 93         end;
 94         inc(j,s);
 95       end;
 96       i:=i shl 1;
 97     end;
 98
 99   end;
100 begin
101   readln(s);
102   len:=length(s);
103   d[0]:=1;
104   for i:=1 to len do
105     d[i]:=d[i-1]*2 mod mo;
106   n:=1;
107   l:=0;
108   while n<=(len-1) shl 1 do
109   begin
110     n:=n*2;
111     inc(l);
112   end;
113   for i:=0 to n-1 do
114     r[i]:=(r[i shr 1] shr 1) or ((i and 1) shl (l-1));
115   for i:=1 to len do
116     if s[i]=‘a‘ then a[i-1].x:=1;
117   fft(a,1);
118   for i:=0 to n-1 do
119   begin
120     b[i]:=a[i]*a[i];
121     a[i].x:=0; a[i].y:=0;
122   end;
123   for i:=1 to len do
124     if s[i]=‘b‘ then a[i-1].x:=1;
125   fft(a,1);
126   for i:=0 to n-1 do
127     b[i]:=b[i]+a[i]*a[i];
128   fft(b,-1);
129   for i:=0 to n-1 do
130   begin
131     x:=trunc(round(b[i].x/n));
132     ans:=(ans+d[(x+1) shr 1]-1) mod mo;
133   end;
134   writeln((ans-manacher+mo) mod mo);
135 end.

时间: 2024-10-24 13:42:31

关于fft的一点总结的相关文章

FFT 模板

FFT(Fast Fourier Transformation/快速傅立叶变换),确切地说应该称之为FDFT(Fast Discrete Fourier Transformation/快速离散傅立叶变换),因为FFT是为解DFT问题而设计的一种快速算法.在深入讨论之前,有必要特别指出这一点. DFT问题: 给定一个复数域上的n-1次多项式A(x)的系数表示(cofficient representation)(a[0], a[1], ..., a[n-1]),求A(x)的某个点-值表示(poin

FFT结果的物理意义

图像的频率是表征图像中灰度变化剧烈程度的指标,是灰度在平面空间上的梯度.如:大面积的沙漠在图像中是一片灰度变化缓慢的区域,对应的频率值很低:而对 于地表属性变换剧烈的边缘区域在图像中是一片灰度变化剧烈的区域,对应的频率值较高.傅立叶变换在实际中有非常明显的物理意义,设f是一个能量有限的模拟信号,则其傅立叶变换就表示f的谱.从纯粹的数学意义上看,傅立叶变换是将一个函数转换为一系列周期函数来处理的.从物理效果看,傅立叶变换是将图像从空间域转换到频率域,其逆变换是将图像从频率域转换到空间域.换句话说,

离散时间序列的内插算法(利用fft)

有些时候,为了后续处理更方便,我们需要对采集到的数据点进行内插处理,也就是所谓的增采样.本文就来讨论一下常用的几种内插算法. 利用FFT实现信号内插 我们的信号 x(t) 是个实信号,带宽有限,能量有限.x[n] =x(nΔ)和 x'[n]  =x(nΔ')是对这个信号的两种采样,并且都满足采样定理的要求,也就是说信息并没有丢失.两次采样的采样率满足如下关系. 也就是说第二种采样的采样率是第一种采样的采样率的M 倍.如果我们有了x'[n],那么很容易获得x[n]: 但是反过来就不是那么容易了.下

HDU 4609 3-idiots FFT+容斥

一点吐槽:我看网上很多分析,都是在分析这个题的时候,讲了半天的FFT,其实我感觉更多的把FFT当工具用就好了 分析:这个题如果数据小,统计两个相加为 x 的个数这一步骤(这个步骤其实就是求卷积啊),完全可以母函数,无奈数据很大,就用FFT了 然后难点在于最后的统计,要减去自身,两个都大的,一大一小,包含自身,这是用到了容斥,再做相似的题的时候,应该多看看这方面 注:再次高度仰慕kuangbin神,这是我FFT的第二题,也是第二次用kuangbin FFT模板 #include <stdio.h>

HDU1402 A * B Problem Plus FFT

分析:网上别家的代码都分析的很好,我只是给我自己贴个代码,我是kuangbin的搬运工 一点想法:其实FFT就是快速求卷积罢了,当小数据的时候我们完全可以用母函数来做,比如那种硬币问题 FFT只是用来解决数据规模较大时的办法,可以达到nlogn的效率,大体原理就是运用了n次单位复根的折半引理 具体可以看算法导论 高度仰慕kuangbin大神的模板,实在是不想自己写 对于这个题,我们10^k的系数看成多项式系数,然后求卷积,进位就好了 #include <stdio.h> #include &l

快速傅里叶变换(FFT)算法【详解】

快速傅里叶变换(Fast Fourier Transform)是信号处理与数据分析领域里最重要的算法之一.我打开一本老旧的算法书,欣赏了JW Cooley 和 John Tukey 在1965年的文章中,以看似简单的计算技巧来讲解这个东西. 本文的目标是,深入Cooley-Tukey  FFT 算法,解释作为其根源的“对称性”,并以一些直观的python代码将其理论转变为实际.我希望这次研究能对这个算法的背景原理有更全面的认识. FFT(快速傅里叶变换)本身就是离散傅里叶变换(Discrete

【BZOJ 4332】 4332: JSOI2012 分零食 (FFT+快速幂)

4332: JSOI2012 分零食 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 119  Solved: 66 Description 这里是欢乐的进香河,这里是欢乐的幼儿园. 今天是2月14日,星期二.在这个特殊的日子里,老师带着同学们欢乐地跳着,笑着.校长从幼儿园旁边的小吃店买了大量的零食决定分给同学们.听到这个消息,所有同学都安安静静地排好了队,大家都知道,校长不喜欢调皮的孩子. 同学们依次排成了一列,其中有A位小朋友,有三个共同的欢乐

快速傅里叶变换(FFT)

快速傅里叶变换(FFT)算法[详解] 快速傅里叶变换(Fast Fourier Transform)是信号处理与数据分析领域里最重要的算法之一.我打开一本老旧的算法书,欣赏了JW Cooley 和 John Tukey 在1965年的文章中,以看似简单的计算技巧来讲解这个东西. 本文的目标是,深入Cooley-Tukey  FFT 算法,解释作为其根源的"对称性",并以一些直观的python代码将其理论转变为实际.我希望这次研究能对这个算法的背景原理有更全面的认识. FFT(快速傅里叶

数字信号处理--FFT与蝶形算法

在数字信号处理中常常需要用到离散傅立叶变换(DFT),以获取信号的频域特征.尽管传统的DFT算法能够获取信号频域特征,但是算法计算量大,耗时长,不利于计算机实时对信号进行处理.因此至DFT被发现以来,在很长的一段时间内都不能被应用到实际的工程项目中,直到一种快速的离散傅立叶计算方法——FFT,被发现,离散傅立叶变换才在实际的工程中得到广泛应用.需要强调的是,FFT并不是一种新的频域特征获取方式,而是DFT的一种快速实现算法.本文就FFT的原理以及具体实现过程进行详尽讲解. DFT计算公式 本文不