[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$ 提出來後約掉)
注意到式子可以分為兩個部分, 這兩個部分中的因子可以分成 $i$ 和 $j-i$ 兩個部分, 即這兩個部分的編號和為 $j$, 那麼我們就找到加法卷積了.
設 $f[i] = \frac$, $g[i] = q_i$.
則$$ e_j = \sum_^ f[j-i] \times g[i] - \sum_^ f[j-i] \times g[i] \]
這樣, 我們就可以分兩步愉快地 fft 了.
需要注意的是, 後半部分的 \(j-i\) 為負數, 所以需要將整個陣列往前移動 \(n\) 位, 最後統計答案的時候也要往前移動 \(n\) 位 (沒聽懂的話可以看一下**).
#include#define _use_math_defines
#define ll long long
#define db double
using namespace std;
const int _=1e5+7;
const int __=3e5+7;
const db pi=m_pi;
struct cn;
} cn operator - (const cn &x) const ;
} cn operator * (const cn &x) const ;
}};int n,n,num[__];
db q[_],e[_];
cn f[__],g[__];
void fft(cn *f,int id);
for(int k=0;k>n;
for(int i=1;i<=n;i++) scanf("%lf",&q[i]);
n=1; while(n<=2*n) n<<=1;
for(ll i=1;i<=n;i++)
for(int i=0;i>1]>>1)|((i&1) ?n>>1 :0);
fft(f,1);
fft(g,1);
for(int i=0;ifft(f,-1);
for(int i=1;i<=n;i++) e[i]=f[i].a/n;
memset(f,0,sizeof(f));
memset(g,0,sizeof(g));
for(ll i=0;i<=n;i++)
f[n].a=0;
fft(f,1);
fft(g,1);
for(int i=0;ifft(f,-1);
for(int i=1;i<=n;i++) printf("%.3lf\n",e[i]-f[i+n].a/n); // 統計答案時也往前移動 n 位
return 0;
}
做題記錄 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...
ZJOI2014 力 FFT基本套路實踐
此文中介紹了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,...
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 顯...