【BZOJ 2194】2194: 快速傅立叶之二(FFT)

2194: 快速傅立叶之二

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 1273  Solved: 745

Description

请计算C[k]=sigma(a[i]*b[i-k]) 其中 k < = i < n ,并且有 n < = 10 ^ 5。 a,b中的元素均为小于等于100的非负整数。

Input

第一行一个整数N,接下来N行,第i+2..i+N-1行,每行两个数,依次表示a[i],b[i] (0 < = i < N)。

Output

输出N行,每行一个整数,第i行输出C[i-1]。

Sample Input

5

3 1

2 4

1 1

2 4

1 4

Sample Output

24

12

10

6

1

HINT

Source

【分析】

  这个卷积也很容易看出来

  C[k]=sigma(a[i]*b[i-k])

  变形,先讲b数组倒置:

  C[k]=sigma(a[i]*b[n-i+k])

  令D[k]=sigma(a[i]*b[k-i])

  则C[k]=D[n+k]

  D数组就是标准卷积了,用FFT加速。

递归:

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<cmath>
 7 using namespace std;
 8 #define Maxn 100010*4
 9 const double pi=3.141592653;
10
11 struct P
12 {
13     double x,y;
14     P() {x=y=0;}
15     P(double x,double y):x(x),y(y){}
16     friend P operator + (P x,P y) {return P(x.x+y.x,x.y+y.y);}
17     friend P operator - (P x,P y) {return P(x.x-y.x,x.y-y.y);}
18     friend P operator * (P x,P y) {return P(x.x*y.x-x.y*y.y,x.x*y.y+x.y*y.x);}
19 }a[Maxn],b[Maxn];
20
21 void fft(P *s,int n,int f)
22 {
23     if(n==1) return;
24     P a0[n>>1],a1[n>>1];
25     for(int i=0;i<=n;i+=2) a0[i>>1]=s[i],a1[i>>1]=s[i+1];
26     fft(a0,n>>1,f);fft(a1,n>>1,f);
27     P wn(cos(2*pi/n),f*sin(2*pi/n)),w(1,0);
28     for(int i=0;i<(n>>1);i++,w=w*wn) s[i]=a0[i]+w*a1[i],s[i+(n>>1)]=a0[i]-w*a1[i];
29 }
30
31 int main()
32 {
33     int n;
34     scanf("%d",&n);n--;
35     for(int i=0;i<=n;i++) scanf("%lf%lf",&a[i].x,&b[i].x);
36     for(int i=0;i<=n/2;i++) swap(b[i].x,b[n-i].x);
37     int nn=1;
38     while(nn<=2*n) nn<<=1;
39     fft(a,nn,1);fft(b,nn,1);
40     for(int i=0;i<=nn;i++) a[i]=a[i]*b[i];
41     fft(a,nn,-1);
42     for(int i=n;i<=n+n;i++) printf("%d\n",(int)(a[i].x/nn+0.5));
43     return 0;
44 }

2017-04-13 10:39:50

时间: 2024-10-25 01:03:24

【BZOJ 2194】2194: 快速傅立叶之二(FFT)的相关文章

【BZOJ 2194】 快速傅立叶之二

2194: 快速傅立叶之二 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 430 Solved: 240 [Submit][Status][Discuss] Description 请计算C[k]=sigma(a[i]*b[i-k]) 其中 k < = i < n ,并且有 n < = 10 ^ 5. a,b中的元素均为小于等于100的非负整数. Input 第一行一个整数N,接下来N行,第i+2..i+N-1行,每行两个数,依次表示a[

BZOJ 2194 快速傅立叶之二 ——FFT

[题目分析] 咦,这不是卷积裸题. 敲敲敲,结果样例也没过. 看看看,卧槽i和k怎么反了. 艹艹艹,把B数组取个反. 靠靠靠,怎么全是零. 算算算,最终的取值范围算错了. 交交交,总算是A掉了. [代码] #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <map> #include <set> #include <

BZOJ.2194.快速傅立叶之二(FFT 卷积)

题目链接 \(Descripiton\) 给定\(A[\ ],B[\ ]\),求\[C[k]=\sum_{i=k}^{n-1}A[i]*B[i-k]\ (0\leq k<n)\] \(Solution\) (先令\(n=n-1\)) 首先往卷积上想.. \(i\)与\(i-k\)的差值是一定的,但是卷积的形式是\[C[k]=\sum_{i=1}^k A[i]*B[k-i]\] 即\(i\)与\(k-i\)的和是一定的. 于是考虑把一个数组反转一下,这里把\(B[\ ]\)反转,那么\[C[k]=

BZOJ 2194: 快速傅立叶之二

2194: 快速傅立叶之二 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1203  Solved: 699[Submit][Status][Discuss] Description 请计算C[k]=sigma(a[i]*b[i-k]) 其中 k < = i < n ,并且有 n < = 10 ^ 5. a,b中的元素均为小于等于100的非负整数. Input 第一行一个整数N,接下来N行,第i+2..i+N-1行,每行两个数,依次表示a

bzoj2194 快速傅立叶之二 ntt

bzoj2194 快速傅立叶之二 链接 bzoj 思路 对我这种和式不强的人,直接转二维看. 发现对\(C_k\)贡献的数对(i,j),都是右斜对角线. 既然贡献是对角线,我们可以利用对角线的性质了. 不过右斜角线不太好,我们把每一行都reverse一下,换成左斜角线. 对角线上\(i+j\)相等,可以套上多项式乘法了. 隐藏bug \(a_i,b_i\)均不大于100,而且数字有1e5个 最大值是1e9,而模数是998244353 应该是可以卡掉模数的,但是不故意卡是不可能爆模数的. AC代码

快速傅立叶变换算法FFT——图像处理中的数学原理详解22

欢迎关注我的博客专栏"图像处理中的数学原理详解" 全文目录请见 图像处理中的数学原理详解(总纲) http://blog.csdn.net/baimafujinji/article/details/48467225 图像处理中的数学原理详解(已发布的部分链接整理) http://blog.csdn.net/baimafujinji/article/details/48751037 交流学习可加图像处理研究学习QQ群(529549320) 傅立叶变换以高等数学(微积分)中的傅立叶级数为基

【BZOJ】2194: 快速傅立叶之二

http://www.lydsy.com/JudgeOnline/problem.php?id=2194 题意:求$c[k]=\sum_{k<=i<n} a[i]b[i-k], n<=10^5$ #include <bits/stdc++.h> using namespace std; struct cp { double x, y; cp(double _x=0, double _y=0):x(_x),y(_y) {} cp operator+(const cp &

BZOJ 2194 快速傅立叶之二 快速傅里叶变换

题目大意:给定两个长度为n的序列a和b,求c[k]=Σa[i]*b[i-k] 这东西不是卷积的形式,因此我们将b数组反转,之后就是卷积的形式了 然后就愉♂悦地上FFT吧 #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 263000 #define PI 3.141592653589793

bzoj 2194: 快速傅立叶之二【NTT】

看别的blog好像我用了比较麻烦的方法-- (以下的n都--过 \[ c[i]=\sum_{j=i}^{n}a[i]*b[j-i] \] 设j=i+j \[ c[i]=\sum_{j=0}^{n-i}a[i+j]*b[i+j-i] \] \[ c[i]=\sum_{j=0}^{n-i}a[i+j]*b[j] \] 再设j=n-i-j \[ c[i]=\sum_{n-i-j}^{n-i}a[n-i-j+i]b[n-i-j] \] \[ n-i-j \geq 0 \Rightarrow j \leq