解题报告(二)C、(darkBZOJ 2194) 快速傅立叶之二(FFT、卷积的概念、常用变换)
繁凡出品的全新系列:解题报告系列 —— 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 111 为基准。
这样大家在学习算法的时候就可以执行这样的流程:
阅读我的【学习笔记】 / 【算法全家桶】学习算法 ⇒\Rightarrow⇒ 阅读我的相应算法的【解题报告】获得高质量题单 ⇒\Rightarrow⇒ 根据我的一句话题解的提示尝试自己解决问题 ⇒\Rightarrow⇒ 点开我的详细题解链接学习巩固(好耶)
%
题单链接:【解题报告】多项式问题(多项式乘法及其各种运算)(ICPC / CCPC / NOIP / CF / AT / NC / P)超高质量题解
C、(BZOJ 2194) 快速傅立叶之二(FFT、卷积的概念、常用变换)
Wbelink
https://darkbzoj.tk/problem/2194
Problem
请计算 C[k]=∑(a[i]∗b[i−k])\displaystyle C[k]=\sum(a[i]*b[i-k])C[k]=∑(a[i]∗b[i−k]) 其中 k<=i<nk < = i < nk<=i<n ,并且有 n<=105n < = 10 ^ 5n<=105。 a,ba,ba,b 中的元素均为小于等于 100100100 的非负整数。
n≤105n \leq 10^5n≤105
Solution
C(x)=A(x)∗B(x)=∑k=02n−2(∑k=i+jaibj)xkC(x)=A(x)* B(x)=\sum_{k=0}^{2n-2}(\sum_{k=i+j}a_ib_j)x^k C(x)=A(x)∗B(x)=k=0∑2n−2(k=i+j∑aibj)xk
我们知道多项式乘法:
C(x)=A(x)∗B(x)=∑i=0n(∑j=0iajbi−j)xj+i−j=∑i=0n(∑j=0iajbi−j)xiC(x)=A(x)*B(x)=\sum_{i = 0}^{n}(\sum_{j=0}^{i}a_j b_{i-j})x^{j+i-j}=\sum_{i = 0}^{n}(\sum_{j=0}^{i}a_j b_{i-j})x^{i} C(x)=A(x)∗B(x)=i=0∑n(j=0∑iajbi−j)xj+i−j=i=0∑n(j=0∑iajbi−j)xi
也就是对于 C(x)C(x)C(x) 的第 kkk 项的系数:
[k]C(x)=∑i=0kaibk−i[k]C(x)=\sum_{i=0}^{k}a_i b_{k-i} [k]C(x)=i=0∑kaibk−i
可以理解为只有小于 kkk 的系数才有可能给 xkx^kxk 做贡献,即 xj×xk−j=xkx^j\times x^{k-j}=x^kxj×xk−j=xk。而大的次幂乘起来就大于 kkk 了。
而本题中要求的式子实际上可以写成:
[k]C(x)=∑i=kn−1aibi−k[k]C(x)=\sum_{i=k}^{n-1}a_ib_{i-k}[k]C(x)=i=k∑n−1aibi−k
发现本题中要求的式子和标准的多项式卷积不太一样,所以考虑如何转化一下。
很明显这两个式子的唯一差别就是卷积循环的是前半部分,题中所求的式子循环的是后半部分,所以我们可以想办法把他们交换一下:我们设 a′a'a′ 是 aaa 数组的翻转,即: a[i]=a′[n−1−i]a[i] = a'[n - 1-i]a[i]=a′[n−1−i] 或 a′[i]=a[n−1−i]a'[i] = a[n - 1-i]a′[i]=a[n−1−i] ,二者等价。 (减一是因为 aaa 数组是从 0∼n−10\sim n-10∼n−1)。
故原式等于:
[k]D(x)=∑i=kn−1an−1−i′bi−k=[n−1−k]C(x)[k]D(x)=\sum_{i=k}^{n-1}a'_{n-1-i}b_{i-k}=[n-1-k]C(x)[k]D(x)=i=k∑n−1an−1−i′bi−k=[n−1−k]C(x)
因为: i:k∼n−1i:k\sim n-1i:k∼n−1
j=n−1−i:n−1−k∼n−1−(n−1)⇒0∼n−1−kj=n-1-i:n-1-k\sim n-1-(n-1) \Rightarrow 0\sim n-1-kj=n−1−i:n−1−k∼n−1−(n−1)⇒0∼n−1−k
[k]D(x)=∑j=n−1−i=0n−1−kan−1−i′bi−k[k]D(x)=\sum_{j=n-1-i=0}^{n-1-k}a'_{n-1-i}b_{i-k}[k]D(x)=j=n−1−i=0∑n−1−kan−1−i′bi−k
n−1−i+i−k=n−1−kn-1-i+i-k=n-1-kn−1−i+i−k=n−1−k 是一个常数。
这样就变成了一个标准的卷积的形式,即可使用 FFT 求解。
Code
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <queue>
using namespace std;
typedef long long ll;
typedef int itn;
typedef pair<int, int>PII;
const int N = 2e5 + 7, mod = 1e9 + 7;const double PI = acos(-1.0);int n, m, RR[N], limit, L;struct Complex
{double x, y;Complex (double x = 0, double y = 0) : x(x), y(y) { }Complex operator + (const Complex &t){return Complex (x + t.x, y + t.y);}Complex operator - (const Complex &t){return Complex (x - t.x, y - t.y);}Complex operator * (const Complex &t){return Complex (x * t.x - y * t.y, x * t.y + y * t.x);}
}A[N], B[N], C[N];void FFT(Complex *A, double type)
{for(int i = 0; i < limit; ++ i)if(i < RR[i])swap(A[i], A[RR[i]]);for(int mid = 1; mid < limit; mid <<= 1) {Complex wn(cos(PI / mid), type * sin(PI / mid));for(int len = mid << 1, pos = 0; pos < limit; pos += len) {Complex w(1, 0);for(int k = 0; k < mid; ++ k, w = w * wn) {Complex x = A[pos + k];Complex y = w * A[pos + mid + k];A[pos + k] = x + y;A[pos + mid + k] = x - y;}}}if(type == -1) {for(int i = 0; i <= limit; ++ i)A[i].x /= limit;}
}//a'[i] = a[n - 1 - i];int main()
{scanf("%d", &n);for(int i = 0; i < n; ++ i) {int x, y;scanf("%d%d", &x, &y);A[n - 1 - i].x = x;B[i].x = y;}L = 0, limit = 1;while(limit <= n * 2) limit <<= 1, L ++ ;for(int i = 0; i < limit; ++ i) {RR[i] = (RR[i >> 1] >> 1) | ((i & 1) << (L - 1));}FFT(A, 1), FFT(B, 1);for(int i = 0; i < limit; ++ i) {C[i] = A[i] * B[i];}FFT(C, -1);for(int i = n - 1; i >= 0; -- i) {printf("%d\n", (int)(C[i].x + 0.5));}return 0;
}
解题报告(二)C、(darkBZOJ 2194) 快速傅立叶之二(FFT、卷积的概念、常用变换)相关推荐
- bzoj 2194 快速傅立叶之二
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2194 因为卷积的第 k 项是 sigma(i=0~k)a[ i ]*b[ k-i ] ,也就 ...
- 【刷题】BZOJ 2194 快速傅立叶之二
Description 请计算C[k]=sigma(a[i]*b[i-k]) 其中 k < = i < n ,并且有 n < = 10 ^ 5. a,b中的元素均为小于等于100的非 ...
- [BZOJ]2194: 快速傅立叶之二
题目大意:给定序列a,b,求序列c满足c[k]=sigma(a[i]*b[i-k]) (k<=i<n).(n<=10^5) 思路:观察发现就是普通的卷积反一反(翻转ab其中一个后做卷 ...
- bzoj2194 快速傅立叶之二
2194: 快速傅立叶之二 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 1730 Solved: 1026 [Submit][Status][D ...
- BZOJ_2194_快速傅立叶之二_(FFT+卷积)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=2194 给出序列\(a[0],a[1],...,a[n-1]\)和\(b[0],b[1],... ...
- bzoj2194: 快速傅立叶之二
了解到了FFT求卷积,但是还是感性的认识.. 取反就可以了.输出一定要加int!!!! #include<cstdio> #include<iostream> #include ...
- BZOJ2194 快速傅立叶之二 【fft】
题目 请计算C[k]=sigma(a[i]*b[i-k]) 其中 k < = i < n ,并且有 n < = 10 ^ 5. a,b中的元素均为小于等于100的非负整数. 输入格式 ...
- BZOJ-2194 快速傅立叶之二
FFT模版题. 观察题目,我们可以发现,只要把序列b倒过来,再联想一下乘法运算... 我们会发现,将序列a和序列b当作100进制数,做一次乘法,然后从低到高每一位便是答案了(乘完无需进位) #incl ...
- 解题报告(二)多项式问题(多项式乘法及其各种运算)(ACM/ OI)超高质量题解
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...
最新文章
- Flutter开发-iOS报错Trying to embed a platform view but the PrerollContext does not s
- java字符串除法函数,java – 函数式编程:如何处理函数式编程中的异常或它的等价物...
- FreeRTOS---堆内存管理(一)
- 解决SQL映射文件的警告提示
- 改ip地址会有什么影响_led显示屏会带来什么负面影响
- Java设计模式:命令模式
- MVC Razor基础
- 2020-11-18
- 防DDoS攻击,你知道自己和其他大型运营商的区别在哪里吗?
- fastadmin使用ECharts制作统计图
- matplotlib模拟重力场中粒子的分布
- kanzi 粒子插件
- 【java实现100以内加减法口算练习程序】
- VMware Tools 服务详解-容易被忽略的螺丝钉
- 关于虚拟专用网的一些概念
- BR系列罗氏电流线圈变送器——安科瑞崔远航
- STK 航空仿真(二)STK MATLAB自动化(1)自动化目的和方法简介
- 解决复制PDF到翻译网站有换行导致翻译错误的问题
- 【使用stripTrailingZeros()函数将BigDecimal去0变为科学计数法7E+1】
- 初中计算机学科知识,初中信息技术学科知识与教学能力讲义-1.PDF