bzoj2194 快速傅利葉之二

2021-10-19 12:46:34 字數 1674 閱讀 3810

題目鏈結

給出兩個長度為n的數列a,b。求乙個數列c滿足:$$c[k] = \sum\limits_ ^ na[i]b[i - k]$$

\(n\le 10^5\)

長得和卷積很像,觀察一下卷積的形式:\(c[k]=\sum\limits_^ia[i]b[k-i]\)

所以先把b陣列翻轉過來

然後所求的式子就變成了\(c[k]=\sum\limits_^na[i]b[n+k-i]\)

將\(n+k\)看做整體,那麼形式就和卷積比較像了,令\(d[n+k]=c[k]=\sum\limits_^na[i]b[n + k - i]\)。因為a的\(n+1\)到\(n+k\)位置均為0,b的\(0\)到\(k-1\)位置均為0.

所以上式也可以寫為\(d[n+k]=\sum\limits_^a[i]b[n+k-i]\)。

這樣就可以借助fft計算了。

注意最後的答案是問c[k],也就是d[k+n]

/*

* @author: wxyww

* @date: 2020-01-22 08:04:15

* @last modified time: 2020-01-22 08:24:04

*/#include#include#include#include#include#include#include#include#includeusing namespace std;

typedef long long ll;

const int n = 400010;

const double pi = 3.1415926535897931;

ll read()

while(c>='0'&&c<='9')

return x*f;

}struct complex a[n],b[n];

complex operator * (const complex &a,const complex &b) ;

}complex operator + (const complex &a,const complex &b) ;

}complex operator - (const complex &a,const complex &b) ;

}int rev[n];

void fft(complex *a,int n,int xs) ;

for(int i = 0;i < n;i += m) ;

for(int k = 0;k < (m >> 1);++k)

} }}int main()

--n;

int tot = 1;

while(tot <= (n << 1)) tot <<= 1;

for(int i = 0;i <= tot;++i) rev[i] = (rev[i >> 1] >> 1) | (i & 1 ? tot >> 1 : 0);

fft(a,tot,1);fft(b,tot,1);

for(int i = 0;i <= tot;++i) a[i] = a[i] * b[i];

fft(a,tot,-1);

for(int i = 0;i <= n;++i) printf("%d\n",(int)round(a[i + n].x / tot));

return 0;

}

bzoj 2194 快速傅利葉之二

time limit 10 sec memory limit 259 mb submit 1314 solved 772 submit status discuss 請計算c k sigma a i b i k 其中 k i n 並且有 n 10 5。a,b中的元素均為小於等於100的非負整數。第一...

BZOJ 2194 快速傅利葉之二

已知 a,b a,b 序列,計算 ck ai bi k ck ai bi k 觀察題目名稱,可以想到fft fft能解決的是形如下面的式子 hk fi gk i hk fi gk i 可以發現,f f 陣列的下標和 g role presentation style position relativ...

bzoj2194 快速傅利葉之二

請計算 c k sum a i times b i k k leq i n 第一行乙個整數 n 接下來 n 行,第 i 2.i n 1 行,每行兩個數,依次表示 a i b i 0 leq i n 輸出 n 行,每行乙個整數,第 i 行輸出 c i 1 5 3 12 4 1 12 4 1 424 1...