生活随笔
收集整理的這篇文章主要介紹了
BZOJ2194 快速傅立叶之二 【fft】
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題目
請計(jì)算C[k]=sigma(a[i]*b[i-k]) 其中 k < = i < n ,并且有 n < = 10 ^ 5。 a,b中的元素均為小于等于100的非負(fù)整數(shù)。
輸入格式
第一行一個整數(shù)N,接下來N行,第i+2..i+N-1行,每行兩個數(shù),依次表示a[i],b[i] (0 < = i < N)。
輸出格式
輸出N行,每行一個整數(shù),第i行輸出C[i-1]。
輸入樣例
5
3 1
2 4
1 1
2 4
1 4
輸出樣例
24
12
10
6
1
題解
和2179幾乎一模一樣
由于卷積的定義要求下標(biāo)之和為常數(shù),我們嘗試將原式變形,發(fā)現(xiàn)只要將a或者b反過來存就可以了
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<complex>
#include<algorithm>
#define pi acos(-1)
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 400005,maxm = 100005,INF = 1000000000;
inline int read(){int out = 0,flag = 1; char c = getchar();while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}while (c >= 48 && c <= 57) {out = (out << 3) + (out << 1) + c - '0'; c = getchar();}return out * flag;
}
typedef complex<double> E;
E a[maxn],b[maxn];
int n,m,L,R[maxn];
void fft(E* a,int f){for (int i = 0; i < n; i++) if (i < R[i]) swap(a[i],a[R[i]]);for (int i = 1; i < n; i <<= 1){E wn(cos(pi / i),f * sin(pi / i));for (int j = 0; j < n; j += (i << 1)){E w(1,0);for (int k = 0; k < i; k++,w *= wn){E x = a[j + k],y = w * a[j + k + i];a[j + k] = x + y; a[j + k + i] = x - y;}}}if (f == -1) for (int i = 0; i < n; i++) a[i] /= n;
}
int main(){n = read(); n--;for (int i = 0; i <= n; i++){a[n - i] = read();b[i] = read();}m = n << 1; for (n = 1; n <= m; n <<= 1) L++;for (int i = 0; i < n; i++) R[i] = (R[i >> 1] >> 1) | ((i & 1) << (L - 1));fft(a,1); fft(b,1);for (int i = 0; i <= n; i++) a[i] *= b[i];fft(a,-1);for (int i = (m >> 1); i >= 0; i--) printf("%d\n",(int)(a[i].real() + 0.1));return 0;
}
轉(zhuǎn)載于:https://www.cnblogs.com/Mychael/p/8350641.html
總結(jié)
以上是生活随笔為你收集整理的BZOJ2194 快速傅立叶之二 【fft】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。