ZJOI2014 力 FFT基本套路實踐

2021-08-11 12:39:01 字數 4116 閱讀 9625

此文中介紹了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 顯...