关于fft的一点总结
好吧,其实我并没有深入运用fft,只会优化卷积
听说fft经常和生成函数结合在一起………………oi真是迅猛发展,我真是与时代脱节了……
关于fft的学习推荐直接去看算法导论,写得非常清楚
主要弄懂n次单位根的相关性质定理(消去定理,折半定理)即可,当然也可以直接背代码……
bzoj2179
模板题,fft可以优化高精度乘法
顺便说一句,pascal可以定义operator,但跑得慢
这题我跑了10s……
uses math;
type point=record
x,y:double;
end;
arr=array[..] of point; var a,b,c:arr;
d,r:array[..] of longint;
i,n,m,l:longint;
s:ansistring; operator +(a,b:point)c:point;
begin
c.x:=a.x+b.x;
c.y:=a.y+b.y;
end; operator -(a,b:point)c:point;
begin
c.x:=a.x-b.x;
c.y:=a.y-b.y;
end; operator *(a,b:point)c:point;
begin
c.x:=a.x*b.x-a.y*b.y;
c.y:=a.x*b.y+a.y*b.x;
end; procedure fft(var a:arr; ty:longint);
var i,j,s,k:longint;
w,p,u,v:point;
begin
for i:= to n- do
if i<r[i] then
begin
w:=a[r[i]];
a[r[i]]:=a[i];
a[i]:=w;
end;
i:=;
while i<n do
begin
p.x:=cos(pi/i);
p.y:=ty*sin(pi/i);
s:=i shl ;
j:=;
while j<n do
begin
w.x:=; w.y:=;
k:=;
while k<i do
begin
u:=a[j+k];
v:=w*a[j+k+i];
a[j+k]:=u+v;
a[j+k+i]:=u-v;
w:=w*p;
inc(k);
end;
inc(j,s);
end;
i:=i shl ;
end;
end; begin
readln(n);
readln(s);
for i:= to n- do
a[n--i].x:=ord(s[i+])-;
readln(s);
for i:= to n- do
b[n--i].x:=ord(s[i+])-;
dec(n);
m:=*n;
n:=;
l:=;
while n<=m do
begin
n:=n shl ;
inc(l);
end;
for i:= to n- do
r[i]:=(r[i shr ] shr ) or ((i and ) shl (l-));
fft(a,); fft(b,);
for i:= to n- do
c[i]:=a[i]*b[i];
fft(c,-);
i:=;
while i<=m do
begin
d[i]:=d[i]+trunc(round(c[i].x/n));
if d[i]>= then
begin
d[i+]:=d[i+]+d[i] div ;
d[i]:=d[i] mod ;
end;
if d[m+]> then inc(m);
inc(i);
end;
for i:=m downto do
write(d[i]);
writeln;
end.
bzoj2194
模板题,倒过来就变成卷积了
不用operator就跑的快多了
type point=record
x,y:double;
end;
arr=array[..] of point; var a,b,c:arr;
r:array[..] of longint;
h,i,n,l,m:longint; procedure fft(var a:arr; ty:longint);
var i,j,k,s:longint;
u,v,p,w:point;
begin
for i:= to n- do
if i<r[i] then
begin
w:=a[r[i]];
a[r[i]]:=a[i];
a[i]:=w;
end; i:=;
while i<n do
begin
p.x:=cos(pi/i);
p.y:=ty*sin(pi/i);
s:=i shl ;
j:=;
while j<n do
begin
w.x:=;
w.y:=;
for k:= to i- do
begin
u:=a[j+k];
v.x:=w.x*a[j+k+i].x-w.y*a[j+k+i].y;
v.y:=w.x*a[j+k+i].y+w.y*a[j+k+i].x;
a[j+k].x:=u.x+v.x;
a[j+k].y:=u.y+v.y;
a[j+k+i].x:=u.x-v.x;
a[j+k+i].y:=u.y-v.y;
u:=w;
w.x:=u.x*p.x-u.y*p.y;
w.y:=u.x*p.y+u.y*p.x;
end;
inc(j,s);
end;
i:=i shl ;
end;
end; begin
readln(n);
h:=n;
for i:= to n- do
readln(a[i].x,b[n--i].x);
m:=*n-;
n:=;
while n<=m do
begin
n:=n*;
inc(l);
end;
for i:= to n- do
r[i]:=(r[i shr ] shr ) or ((i and ) shl (l-));
fft(a,);
fft(b,);
for i:= to n- do
begin
c[i].x:=a[i].x*b[i].x-a[i].y*b[i].y;
c[i].y:=a[i].x*b[i].y+a[i].y*b[i].x;
end;
fft(c,-);
for i:=h- to m do
writeln(round(c[i].x/n)); end.
bzoj3527
给一下题面吧,
, 令 Ei=Fi/qi,求Ei
带进去稍微弄弄就是卷积啊……
type point=record
x,y:extended;
end;
arr=array[..] of point; var a,b,c:arr;
ans,d:array[..] of extended;
r:array[..] of longint;
i,n,m,l:longint; procedure fft(var a:arr; ty:longint);
var i,j,k,s:longint;
w,p,u,v:point;
begin
for i:= to n- do
if i<r[i] then
begin
w:=a[r[i]];
a[r[i]]:=a[i];
a[i]:=w;
end; i:=;
while i<n do
begin
p.x:=cos(pi/i);
p.y:=ty*sin(pi/i);
s:=i shl ;
j:=;
while j<n do
begin
w.x:=;
w.y:=;
for k:= to i- do
begin
u:=a[j+k];
v.x:=w.x*a[j+k+i].x-w.y*a[j+k+i].y;
v.y:=w.x*a[j+k+i].y+w.y*a[j+k+i].x;
a[j+k].x:=u.x+v.x;
a[j+k].y:=u.y+v.y;
a[j+k+i].x:=u.x-v.x;
a[j+k+i].y:=u.y-v.y;
u:=w;
w.x:=u.x*p.x-u.y*p.y;
w.y:=u.x*p.y+u.y*p.x;
end;
inc(j,s);
end;
i:=i shl ;
end;
if ty=- then
begin
for i:= to n- do
a[i].x:=a[i].x/extended(n);
end;
end; begin
readln(n);
m:=n;
n:=;
while n<=*(m-) do
begin
n:=n shl ;
inc(l);
end;
for i:= to n- do
r[i]:=(r[i shr ] shr ) or ((i and ) shl (l-));
for i:= to m- do
readln(d[i]);
for i:= to m- do
begin
a[i].x:=d[i];
if i<> then b[i].x:=/i/i;
end;
fft(a,); fft(b,);
for i:= to n- do
begin
c[i].x:=a[i].x*b[i].x-a[i].y*b[i].y;
c[i].y:=a[i].x*b[i].y+a[i].y*b[i].x;
end;
fft(c,-);
for i:= to m- do
ans[i]:=c[i].x; for i:= to n- do
begin
a[i].x:=;
a[i].y:=;
if i<m then a[i].x:=d[m--i];
end;
fft(a,);
for i:= to n- do
begin
c[i].x:=a[i].x*b[i].x-a[i].y*b[i].y;
c[i].y:=a[i].x*b[i].y+a[i].y*b[i].x;
end;
fft(c,-);
for i:= to m- do
begin
ans[i]:=ans[i]-c[m-i-].x;
writeln(ans[i]::);
end;
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的速度,但要慎用,有时候会出错
uses math;
const mo=;
type point=record
x,y:double;
end;
arr=array[..] of point; var a,b:arr;
p,d,r:array[..] of longint;
c:array[..] of char;
s:ansistring;
x,n,l,len,i,ans:longint; operator +(a,b:point)c:point;inline;
begin
c.x:=a.x+b.x;
c.y:=a.y+b.y;
end; operator -(a,b:point)c:point;inline;
begin
c.x:=a.x-b.x;
c.y:=a.y-b.y;
end; operator *(a,b:point)c:point;inline;
begin
c.x:=a.x*b.x-a.y*b.y;
c.y:=a.x*b.y+a.y*b.x;
end; function min(a,b:longint):longint;
begin
if a>b then exit(b) else exit(a);
end; function manacher:longint;
var w,t,i,right,k:longint;
begin
c[]:='$';
t:=;
for i:= to len do
begin
inc(t); c[t]:='#';
inc(t); c[t]:=s[i];
end;
c[t+]:='#';
right:=; k:=;
w:=;
for i:= to t do
begin
if right>i then p[i]:=min(p[*k-i],right-i)
else p[i]:=;
while c[i+p[i]]=c[i-p[i]] do inc(p[i]);
w:=(w+p[i] div ) mod mo;
if p[i]+i>right then
begin
right:=p[i]+i;
k:=i;
end;
end;
exit(w);
end; procedure fft(var a:arr; ty:longint);
var i,j,k,s:longint;
w,p,u,v:point;
begin
for i:= to n- do
if i<r[i] then
begin
w:=a[r[i]];
a[r[i]]:=a[i];
a[i]:=w;
end;
i:=;
while i<n do
begin
p.x:=cos(pi/i);
p.y:=ty*sin(pi/i);
s:=i shl ;
j:=;
while j<n do
begin
w.x:=; w.y:=;
for k:= to i- do
begin
u:=a[j+k];
v:=w*a[j+k+i];
a[j+k]:=u+v;
a[j+k+i]:=u-v;
w:=w*p;
end;
inc(j,s);
end;
i:=i shl ;
end; end;
begin
readln(s);
len:=length(s);
d[]:=;
for i:= to len do
d[i]:=d[i-]* mod mo;
n:=;
l:=;
while n<=(len-) shl do
begin
n:=n*;
inc(l);
end;
for i:= to n- do
r[i]:=(r[i shr ] shr ) or ((i and ) shl (l-));
for i:= to len do
if s[i]='a' then a[i-].x:=;
fft(a,);
for i:= to n- do
begin
b[i]:=a[i]*a[i];
a[i].x:=; a[i].y:=;
end;
for i:= to len do
if s[i]='b' then a[i-].x:=;
fft(a,);
for i:= to n- do
b[i]:=b[i]+a[i]*a[i];
fft(b,-);
for i:= to n- do
begin
x:=trunc(round(b[i].x/n));
ans:=(ans+d[(x+) shr ]-) mod mo;
end;
writeln((ans-manacher+mo) mod mo);
end.
关于fft的一点总结的更多相关文章
- FFT与NTT的模板
网上相关博客不少,这里给自己留个带点注释的模板,以后要是忘了作提醒用. 以洛谷3803多项式乘法裸题为例. FFT: #include <cstdio> #include <cmat ...
- 算法系列:FFT 002
转载自http://blog.jobbole.com/58246/ 快速傅里叶变换(Fast Fourier Transform)是信号处理与数据分析领域里最重要的算法之一.没有正规计算机科学课程背景 ...
- 关于一个通俗易懂的FFT的C语言实现教程
找到一个通俗易懂并且神奇并且有趣的FFT算法C语言实现教程:http://www.katjaas.nl/FFTimplement/FFTimplement.html 只要对矩阵比较熟悉就能在教程的辅助 ...
- 数字信号处理--FFT与蝶形算法
在数字信号处理中常常需要用到离散傅立叶变换(DFT),以获取信号的频域特征.尽管传统的DFT算法能够获取信号频域特征,但是算法计算量大,耗时长,不利于计算机实时对信号进行处理.因此至DFT被发现以来, ...
- 数字信号处理--FFT
FFT是离散傅立叶变换的快速算法,可以将一个信号变换到频域.有些信号在时域上是很难看出什么特征的,但是如果变换到频域之后,就很容易看出特征了.这就是很多信号分析采用FFT变换的原因.另外,FFT可以将 ...
- FFT入门
这篇文章会讲讲FFT的原理和代码. 先贴picks博客(又名FFT从入门到精通):http://picks.logdown.com/posts/177631-fast-fourier-transfor ...
- FFT的物理意义
来源:学步园 FFT(Fast Fourier Transform,快速傅立叶变换)是离散傅立叶变换的快速算法,也是我们在数字信号处理技术中经常会提到的一个概念.在大学的理工科课程中,在完成高等数学的 ...
- FFT结果的物理意义
图像的频率是表征图像中灰度变化剧烈程度的指标,是灰度在平面空间上的梯度.如:大面积的沙漠在图像中是一片灰度变化缓慢的区域,对应的频率值很低:而对 于地表属性变换剧烈的边缘区域在图像中是一片灰度变化剧烈 ...
- HDU 4609 3-idiots FFT+容斥
一点吐槽:我看网上很多分析,都是在分析这个题的时候,讲了半天的FFT,其实我感觉更多的把FFT当工具用就好了 分析:这个题如果数据小,统计两个相加为 x 的个数这一步骤(这个步骤其实就是求卷积啊),完 ...
随机推荐
- ascx aspx ashx asmx 文件的作用
ascx aspx ashx asmx 文件的作用 ascx: Ascx 是给予Web的用户控件(UserControl),一般是用来重用的,不能直接被访问只能插入aspx页面呈现.头部文件<% ...
- 华为章宇:如何学习开源项目及Ceph的浅析
转自http://www.csdn.net/article/2014-04-10/2819247-how-to-learn-opensouce-project-&-ceph 摘要:开源技术的学 ...
- HTML+CSS入门
<strong>加粗</strong> <em>斜体</em> <p>段落</p> <span>设置单独样式< ...
- cookieContainer应用
PublicSharedFunctionGetCookiesSetByPage(ByVal strUrl AsString,ByVal cookieToProvide AsString)AsIEnum ...
- DevExpress控件使用系列--ASPxTreeList
控件功能 结合列表控件及树控件的优点,在列表控件中实现类型树的多层级操作 官方说明 http://documentation.devexpress.com/#AspNet/clsDevExpres ...
- Python新式类和旧式类的区别
新式类是为了统一**而在2.2中开始引入的. 代码讲解 上面的例子比较明白的说明了问题. B是定义的新式类.那么输入b的时候,不论是type(b),还是b.__class__都是输出的<clas ...
- C内存分配函数
C语言跟内存分配方式(1) 从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量.(2) 在栈上创建.在执行函数时,函数内局部变量的 ...
- iOS开发--网络下载
这里使用的是NSURLConnection的代理请求下载,并且是具有进度,UI能实时刷新,至于NSURLConnection如何请求.并且有几种请求方法请看NSURLConnection请求简介,在这 ...
- Lambda 表达式型的排序法
int[] arry = {3,9,5,7,64,51,35,94 }; foreach (int i in arry.OrderBy(i => i)) Console.WriteLine(i) ...
- PowerDesigner连接Oracle数据库建表序列号实现自动增长
原文:PowerDesigner连接Oracle数据库建表序列号实现自动增长 创建表就不说了.下面开始介绍设置自动增长列. 1 在表视图的列上创建.双击表视图,打开table properties — ...