卷积

现有两个定义在 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. VIJOS-P1167 南蛮图腾

    洛谷 P1498 南蛮图腾 洛谷传送门 JDOJ 1325: VIJOS-P1167 南蛮图腾 JDOJ传送门 Description 自从到了南蛮之地,孔明不仅把孟获收拾的服服帖帖,而且还发现了不少 ...

  2. redhat7.7(centOS7)安装ORACLE 11g出坑教程及问题总结与解决

    写在前面: 环境建议:VM 15.5,因为15.5修复了诸多bug,可以在安装过程中省去不少麻烦 添加新的虚拟机安装redhat7.7 准备redhat7.7的安装包...百度云不让上传噢噢噢噢,这里 ...

  3. Windows下同时安装python2和python3如何兼容版本

    引言:因学习需要把python2和python3都安装了,为了避免使用过程中混淆版本在网上找了一些解决方案,亲测可用.方法如下: 分别下载并安装Python2.x和Python3.x. 配置环境变量. ...

  4. ZEN、ELECTRA、ALBERT

    一.ZEN 目前,大多数中文预训练模型基本上沿用了英文模型的做法,聚焦于小颗粒度文本单元(字)的输入.然而,与英文相比,中文没有空格等明确的词语边界.这个特点使得很多文本表达中存在的交叉歧义也被带入了 ...

  5. 腾讯云服务器centos7.2+nginx(开启gzip压缩)+uwsgi+Django+react

    因为项目原因,学习了react,Django,完成react开发项目过后,打包(做好了代码分割.压缩)放入Django中,在本地运行速度很快,结果放到服务器中,虽然某些js文件很小(只有一百多kb), ...

  6. React: React脚手架

    一.简言 React开发目前已经非常流行,对于如何实现对React项目的管理和维护,React生态圈出现了大量可用的开发工具,例如Browserify.Gulp.Grunt.webpack等.其中,w ...

  7. ExtJS布局控件

    Layout Controls Auto Layout Ext JS4中的容器的默认布局是自动布局.这个布局管理器会自动地将组件放在一个容器中. Fit Layout Fit布局安排了容器的内容完全占 ...

  8. Leetcode练习题Longest Common Prefix

    Question: Longest Common Prefix Write a function to find the longest common prefix string amongst an ...

  9. Seven Kinds of Testers - 七种类型的测试

    最近读了James大叔的一篇总结Tester类型的文章,获益良多.原文叫做Seven Kinds of Testers(链接:http://www.satisfice.com/blog/archive ...

  10. 【洛谷2791】幼儿园篮球题(第二类斯特林数,NTT)

    [洛谷2791]幼儿园篮球题(第二类斯特林数,NTT) 题面 洛谷 题解 对于每一组询问,要求的东西本质上就是: \[\sum_{i=0}^{k}{m\choose i}{n-m\choose k-i ...