ZJOI2014 力 解題報告

2022-04-07 10:02:06 字數 1572 閱讀 2698

[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 顯...