此文中介紹了fft的基本套路:
[bzoj]4503 兩個串:我的第一次fft嘗試本題便是對fft基本套路的又一次實踐,即翻轉乙個串,把對應相乘被轉化成卷積。
給出n 個數qi
,fj 的定義如下: fj
=∑iiqj(
i−j)
2−∑i
>jq
iqj(
i−j)
2 令:e
i=fi
/qi ,求ei
。
第一行乙個數n,接下來n行每行乙個數,第i行的數為qi。
n行,第i行的數表示ei。
5
4006373.885184
15375036.435759
1717456.469144
8514941.004912
1410681.345880
-16838672.693
3439.793
7509018.566
4595686.886
10903040.872
把fj
中的所有qj
都提出來,有:fj
=qj⋅
(∑ii(i−
j)2−
∑i>jq
i(i−
j)2)
所以有:ei
=fiq
i=∑i
i(i−
j)2−
∑i>jq
i(i−
j)2
把這個式子拆成兩半,令:f(
j)=∑
ii(i−
j)2=
∑i=0
j−1q
i(i−
j)2
g(j)
=∑i>jq
i(i−
j)2=
∑i=j
+1n−
1qi(
i−j)
2=∑i
=j+1
nqi(
i−j)
2 則有:ei=
f(i)
−g(i
) 先看f
(i) :f(
j)=∑
j−1i
=0qi
(i−j
)2,不妨令i=
j−i (調整迴圈順序,結果不變),有:f(
j)=∑
(j−i
)=0(
j−i)
=j−1
qj−i
((j−
i)−j
)2=∑
i=1j
qj−i
i2定義向量a,b,使得:ai
=qi ,bi
=1i2
(i∈1..n)
,特別地,b0
=0。則有:f(
j)=∑
i=1j
qj−i
⋅1i2
=∑i=
0jaj
−i⋅b
i 令向量c為,向量a、b的卷積。即:c=
a×b ,有:ck
=∑i+
j=ka
j⋅bi
=∑i=
0kak
−i⋅b
i 由此證明:f(
j)=c
j=(a
×b)j
然後考慮g(
j):g(j
)=∑n
i=j+
1qi(
i−j)
2 不妨令i=
j−i (同上文,調整迴圈順序,結果不變),有:g(
j)=∑
j−i=
j+1j
−i=n
qj−i
((j−
i)−j
)2=∑
i=j−
n−1q
j−i(
−i)2
i小於零看著太彆扭,再令i=
−i,有:g(
j)=∑
i=1n
−jqj
+ii2
=∑i=
1n−j
qj+i
⋅1i2
=∑i=
0n−j
aj+i
⋅bi
此時,我們發現,i與j+i的差是乙個定值。
定義乙個向量b′
,使得b′
i=bn
−i,即對b向量進行翻轉。那麼就有:g(
j)=∑
i=0n
−jaj
+i⋅b
′n−i
這次,不難看出,n-i與j+i的和是乙個定值了。
定義向量c′
,有c′
=a×b
′ ,即:c′
k=∑i
+j=k
ai⋅b
′j=∑
i=0k
ai⋅b
′k−i
那麼:c′
n+j=
∑i=0
n+ja
i⋅b′
n+j−
i 令i
=j+i
,有:c′
n+j=
∑j+i
=0j+
i=n+
jaj+
i⋅b′
n+j−
(j+i
)=∑i
=−jn
aj+i
⋅b′n
−i 當
i<
0 時,n−
i>
n ,b′
n−i=
0 ,可以不考慮;當
i>n−
j 時,j+
i>
n ,aj
+i=0
,也可以不考慮,所以:c′
n+j=
∑i=−
jnaj
+i⋅b
′n−i
=∑i=
0n−j
aj+i
⋅b′n
−i=g
(j)
結合上文中所述,我們可以利用fft以o(
nlgn
) 的時間複雜度計算卷積c=
a×b 和c′
=a×b
′ 。輸出的結果就是ei
=ci−
c′n+
i 。
#include
#include
#include
using
namespace
std;
typedef
complex
cd;#include
#include
#define maxl ((100000+3)*4)
cd a[maxl],b[maxl],invb[maxl];
cd f[maxl],g[maxl];
double ans[maxl];
int rev[maxl];
void get_rev(int bit)
}void fft(cd* a,int n,int dft)
for(int i=1;i<=n;i++)b[i]=1.0/i/i;
for(int i=0;i<=n;i++)invb[i]=b[n-i];
int bit,s;
for(bit=1,s=2;(1
<1))-1;bit++)s<<=1;
get_rev(bit);
fft(a,s,1);fft(b,s,1);fft(invb,s,1);
for(int i=0;i//printf("f[%d]=(%lf,%lf)\n",i,f[i].real(),f[i].imag());
g[i]=a[i]*invb[i];
}fft(f,s,-1);fft(g,s,-1);
for(int i=0;iprintf("%.3lf\n",ans[i]);
}return
0;}
ZJOI2014 力 解題報告
zjoi2014 力 給出 n 個數 q i 定義 f j sum frac sum frac e i frac 求 e i i in 1,n 首先,提公因式,化簡可以得到,e j sum frac sum frac 把 q j 提出來後約掉 注意到式子可以分為兩個部分,這兩個部分中的因子可以分成 ...
做題記錄 ZJOI2014 力
給出 n 個數 q 1,q 2,dots q n 定義 f j sum frac sum frac e i frac 對 1 leq i leq n 求 e i 的值。f j sum frac sum frac 即求 e i frac sum i frac sum n frac 令 x i dfra...
ZJOJ2014 力 解題報告 FFT
題目 給出 n 個數 q i 令 f j sum frac e i frac 求 e i 題解 顯然 e j sum frac sum frac 不妨設 g i frac,g 0 0 t i q i,t 0 0 那麼 e j sum t ig sum t ig sum t ig sum t ig 顯...