卷积

现有两个定义在 N 上的函数 \(f(n),g(n)\),定义 \(f\) 和 \(g\) 的卷积(convolution)为 \(f \otimes g\)

\[(f \otimes g)(n) = \sum_{i=0}^n f(i)g(n-i)
\]

示意图: from http://blog.miskcoo.com/2015/04/polynomial-multiplication-and-fast-fourier-transform#i-17

考虑两多项式 \(A, B\) 的乘积 \(C\), \(c(x) = \sum_{i=0}^{x} a(i) \cdot b(x - i)\)

系数记为卷积形式

于是计算卷积 \((f \otimes g)(n)\) 就可以把 \(f, g\) 的值直接作为系数写成两个多项式, 然后 FFT 计算多项式乘积, 得到的系数的前 \(n\) 项即为所求

BZOJ3527[ZJOI2014]力

题意:

给出 \(n\) 个数 \(q_i\) ,给出 \(F_j\) 的定义如下:

\[F_j = \sum_{i < j}\frac{q_i q_j}{(i - j) ^ 2} - \sum_{i > j}\frac{q_i q_j}{(i - j) ^ 2}
\]

令 \(E_j = F_j / q_j\) , 求 \(E_j\)

Sol:

因为知道是卷积的例题了, 所以想着把这个式子往卷积的方向靠

\[\begin{aligned}
E_j = \sum_{i < j}\frac{q_i}{(i - j) ^ 2} - \sum_{i > j}\frac{q_i}{(i - j) ^ 2}
\end{aligned}
\]

考虑分母当做系数, 再考虑下标和为 \(j\) , 写成这样

\[\begin{aligned}
E_j = \sum_{i < j}\frac{1}{(j - i) ^ 2}q_i - \sum_{i > j}\frac{1}{(j - i) ^ 2}q_i
\end{aligned}
\]

一开始想把两个一起做, 发现写不出两个函数, 于是考虑分开做

显然 \(\sum_{i < j}\frac{1}{(j - i) ^ 2}q_i\) 就是 \(f(n) = q_n\) 和 \(g(n) = \frac{1}{n^2}\) 的卷积

然后后面一项同理, 把 \(f(n)\) 翻转一下即可

然后跑 FFT

double ans[MAXN], q[MAXN];

/*
20191212
0859~0922~0939
BZOJ3527 FFT
*/ int main()
{
scanf("%d", &lena);
for (int i = 0; i < lena; ++ i)
{
scanf("%lf", &a[i].x); q[lena - 1 - i] = a[i].x;
b[i].x = (i == 0 ? 0.0 : 1.0 / i / i);
}
while ((1 << dgt) < lena * 2) ++ dgt;
n = 1 << dgt;
init(n, dgt);
FFT(b, n ,1);
FFT(a, n, 1);
for (int i = 0; i < n; ++ i) a[i] = a[i] * b[i];
FFT(a, n, -1);
for (int i = 0; i < lena; ++ i) ans[i] += a[i].x / n;
for (int i = 0; i < n; ++ i) a[i].x = q[i], a[i].y = 0;
FFT(a, n, 1);
for (int i = 0; i < n; ++ i) a[i] = a[i] * b[i];
FFT(a, n, -1);
for (int i = 0; i < lena; ++ i) ans[i] -= a[lena - 1 - i].x / n;
for (int i = 0; i < lena; ++ i) printf("%.3f\n", ans[i]);
return 0;
}
/*
3
1 2 3
*/

字符串匹配

给定两个字符串 \(A, B, |A| \ge |B|\), 用 \(B\) 取匹配 \(A\),

那么可以发现对应位置的差恒定, 要转化成卷积形式, 可以将 \(B\) 翻转, 于是就可以构造卷积了

BZOJ4892[Tjoi2017]DNA

题意:

多测, 给两个字符串 \(A, B\), 字符集是 ACGT, 匹配的定义是相差不超过 3 个字符, 求 \(B\) 在 \(A\) 中匹配的次数

\(n \le 1e5, T \le 10\)

Sol:

翻转 \(B\)

一开始构造了这样的 : \(ans_i = \sum_{j=0}^i (a_j - b_{i - j}) ^ 2 \cdot a_j \cdot b_{i-j}\)

然后单独计算 \(B\) 中四个字符的贡献, 36 个 FFT

其实不需要这么套路, 反正都单独计算了, 可以更加钦点一点

\(ans_i = \sum_{j=0}^i a_j \cdot b_{i-j}\)

\(B\) 中是枚举的字符就 1 否则 0 , \(A\) 中相反

这样得到的某一位卷积就是不一样的个数

int ans[MAXN];
void read(int * a, int & len)
{
scanf("%s", tmp);
len = strlen(tmp);
for (int i = 0; i < len; ++ i)
if (tmp[i] == 'A') a[i] = 0;
else if (tmp[i] == 'G') a[i] = 1;
else if (tmp[i] == 'C') a[i] = 2;
else a[i] = 3;
}
int fpow(int a, int b)
{
int ret = 1;
for (int i = 1; i <= b; ++ i) ret *= a;
return ret;
} void solve(int x)
{
for (int i = 0; i < n; ++ i) ca[i] = cb[i] = 0;
for (int i = 0; i < lena; ++ i)
{
if (sa[i] == x) ca[i] = 0;
else ca[i] = 1;
}
for (int i = 0; i < lenb; ++ i)
{
if (sb[i] == x) cb[i] = 1;
else cb[i] = 0;
}
for (int i = 0; i < n; ++ i)
a[i] = (Cpx) { ca[i], 0 }, b[i] = (Cpx) { cb[i], 0 };
FFT(a, n, 1); FFT(b, n, 1);
for (int i = 0; i < n; ++ i) a[i] = a[i] * b[i];
FFT(a, n, -1);
for (int i = 0; i < n; ++ i)
ans[i] += (int)(a[i].x / n + 0.5);
} int main()
{
int T;
scanf("%d", &T);
while (T --)
{
read(sa, lena);
read(sb, lenb);
reverse(sb + 0, sb + lenb);
n = 1, dgt = 0;
while (n < lena + lenb) n <<= 1, ++ dgt;
init(n, dgt);
for (int i = 0; i < n; ++ i) ans[i] = 0;
for (int i = 0; i < 4; ++ i) solve(i);
int cnt = 0;
for (int i = lenb - 1; i < lena; ++ i)
if (ans[i] <= 3) ++ cnt;
printf("%d\n", cnt);
}
return 0;
} /*
2
ATCGCCCTA
CTTCA
ACGT
GTCA
*/

FFT_应用和例题的更多相关文章

  1. BIT 树状数组 详解 及 例题

    (一)树状数组的概念 如果给定一个数组,要你求里面所有数的和,一般都会想到累加.但是当那个数组很大的时候,累加就显得太耗时了,时间复杂度为O(n),并且采用累加的方法还有一个局限,那就是,当修改掉数组 ...

  2. STL模板中的map的使用与例题

    最近的计分赛,记得自己的都只是过了两题.遇到了两次map,自己在寒假看了一点的map,只知道在字符串匹配的时候可以用的到.但是自己对map的使用还是不够熟练使用,这回在第一次和第二次的计分赛中都遇到可 ...

  3. C语言经典例题100

    C语言经典例题100 来源 http://www.fishc.com 适合初学者 ----------------------------------------------------------- ...

  4. 图的全局最小割的Stoer-Wagner算法及例题

    Stoer-Wagner算法基本思想:如果能求出图中某两个顶点之间的最小割,更新答案后合并这两个顶点继续求最小割,到最后就得到答案. 算法步骤: --------------------------- ...

  5. lca入门———树上倍增法(博文内含例题)

    倍增求LCA: father[i][j]表示节点i往上跳2^j次后的节点 可以转移为 father[i][j]=father[father[i][j-1]][j-1] 整体思路: 先比较两个点的深度, ...

  6. acm常见算法及例题

    转自:http://blog.csdn.net/hengjie2009/article/details/7540135 acm常见算法及例题  初期:一.基本算法:     (1)枚举. (poj17 ...

  7. [LeetCode] “全排列”问题系列(二) - 基于全排列本身的问题,例题: Next Permutation , Permutation Sequence

    一.开篇 既上一篇<交换法生成全排列及其应用> 后,这里讲的是基于全排列 (Permutation)本身的一些问题,包括:求下一个全排列(Next Permutation):求指定位置的全 ...

  8. C语言中的经典例题用javascript怎么解?(一)

    C语言中的经典例题用javascript怎么解?(一) 一.1+2+3+……+100=?        <script type="text/javascript">  ...

  9. 数据库留言板例题:session和cookie区别

    session和cookie区别: <?php session_start(); //session_start();必须写在所有的php代码前边 ?> <!DOCTYPE html ...

随机推荐

  1. flask之请求与响应、闪现(阅后即焚)、请求扩展(before,after)、中间件、LOCAL对象、偏函数、

    目录 1.flask请求与响应 2.闪现 3.请求扩展 4.中间件 5.LOCAL对象 6.偏函数 templates 1.flask请求与响应 from flask import Flask,req ...

  2. Vue 监听键盘,键盘修饰符keyup

    附录:键盘Key Code对照表 代码: <!doctype html> <html lang="en"> <head> <meta ch ...

  3. Kettle在windows上安装

    Kettle是一款国外开源的ETL工具,纯java编写,可以在Windows.Linux.Unix上运行,数据抽取高效稳定. 因为有个日常提数,工作日每天都要从数据库中提取数据,转换为excel,再以 ...

  4. yolov3和ssd的区别

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/BlowfishKing/article/d ...

  5. VS2019安装好后,经常打不开软件没反应解决方法

    原文地址:https://blog.csdn.net/FL1623863129/article/details/89013137 VS2019于昨日正式发布,博主立马下载一个专业版尝尝鲜,但是发现项目 ...

  6. WPF——如何为项目设置全局样式。

    在项目中,需要为所有的Button.TextBox设置一个默认的全局样式,一个个的为多个控件设置相同的样式显然是不明智的.在WPF中可以通过资源设置全局样式,主要有俩种方法: 1.第一种就是先写好按钮 ...

  7. 帝国CMS标签【操作类型】说明详解

    看标签的参数时候,一般最后一个参数是操作类型说明,可是后面写的是:"操作类型说明 具体看操作类型说明", 这个操作类型说明在什么地方看啊 操作类型 说明 操作类型 说明 0 各栏目 ...

  8. linux shell中$0,$?,$!等的特殊用法

    记录下linux shell下的特殊用法及参数的说明 变量说明: $$Shell本身的PID(ProcessID)$!Shell最后运行的后台Process的PID$?最后运行的命令的结束代码(返回值 ...

  9. Define the Data Model and Set the Initial Data 定义数据模型并设置初始数据

    This topic describes how to define the business model and the business logic for WinForms and ASP.NE ...

  10. git 配置远程仓库(同一个邮箱注册多个gitlab仓库)

    之前配置的全局用户和邮箱,如果是多个注册账户就不能设置为全局账户 git config --global user.name "username" git config --glo ...