关于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 的个数这一步骤(这个步骤其实就是求卷积啊),完 ...
随机推荐
- [原创] zabbix学习之旅四:mail客户端安装
相信大家使用zabbix的最主要目的就是当被监控机器发生故障时,能通过zabbix获得第一时间的报警提醒.zabbix常用的报警媒介有email,短信,jabber和脚本,这其中脚本类型最为灵活,尤其 ...
- JAVA里的String、Timestamp、Date相互转换(转)
转自:http://blog.sina.com.cn/s/blog_6675493d0100lbfl.html Timestamp转化为String: SimpleDateFormat df = ne ...
- 3240: [Noi2013]矩阵游戏
Description 婷婷是个喜欢矩阵的小朋友,有一天她想用电脑生成一个巨大的n行m列的矩阵(你不用担心她如何存储).她生成的这个矩阵满足一个神奇的性质:若用F[i][j]来表示矩阵中第i行第j列的 ...
- C#快速排序算法基础入门篇
相信算法对于许多开发人员来说都是一大难点,之所以难,就像设计模式一样,许多人在阅读之后,没有很好地理解,也不愿意动手上机操作,只停留在理论的学习上面,随着时间推移就慢慢淡忘. 有些东西,你可以发明创造 ...
- NGUI UIGrid 动态刷新布局 && BUG FIX
/// <summary> /// "1" => 对应的一个UISpirte,"1234" => 对应四个预设 /// </sum ...
- ERROR: JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = -2 JDWP exit error AGENT_ERROR_NO_JNI_ENV(183):
eclipse中进行java debug调试时出现上述问题. solution:请在代码最后加入以下语句:System.exit(0)即可.
- hdu 1233 还是畅通工程(最小生成树,基础)
题目 //也是标准的最小生成树啊,我就改一点点,不重新再打一遍增加熟练度了 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #inclu ...
- 深入浅出ES6(六):解构 Destructuring
作者 Jason Orendorff github主页 https://github.com/jorendorff 什么是解构赋值? 解构赋值允许你使用类似数组或对象字面量的语法将数组和对象的属性 ...
- hdu1301Jungle Roads
http://acm.hdu.edu.cn/showproblem.php?pid=1301 最小生成树模板题 #include<iostream> #include<stdio.h ...
- 阿里巴巴fastJson
FastJson解析 一.阿里巴巴FastJson是一个Json处理工具包,包括“序列化”和“反序列化”两部分,它具备如下特征:速度最快,测试表明,fastjson具有极快的性能,超越任其他的Java ...