一道fft練習題

2021-10-01 12:47:33 字數 2918 閱讀 7633

考場上想到的o(n

2)o(n^2)

o(n2

)暴力:

記f [i

][j]

f[i][j]

f[i][j

]表示前i個位置,長度為j的連擊出現的期望次數

記g [i

][j]

g[i][j]

g[i][j

]表示第到i個位置為止,目前連擊次數為j的概率

轉移時有一些細節

#include

using

namespace std;

const

int maxn=

5e4+5;

inline

intread()

while

(isdigit

(c))

return t*f;

}int n;

double a[maxn]

,f[2

][maxn]

,g[2

][maxn]

;int

main()

g[i&1]

[0]=

0;f[i&1]

[0]=

0;for(

int j=

1;j<=i;j++

)for

(int j=

0;jfor(

int i=

1;i<=n;i++

) f[n&1]

[0]=

0;for(

int i=

0;i<=n;i++

)return0;

}

然後是正解:

記p[i]表示前i個位置都連擊,在第i+1個位置斷連的概率

記q[i]表示恰好從第i個位置開始連擊的概率.

記ans[i]表示最終連擊長度恰好為i的期望次數

然後發現如果將p或q翻轉,ans可以直接由p和q多項式乘法得到

這裡首先給出暴力,更便於理解

#include

const

int maxn=

50005

;double a[maxn]

,s[maxn]

,p[maxn]

,q[maxn]

,ans[maxn]

;int n,i,j;

intmain()

for(i=

0;i<=n;i++

)for

(i=1

;i<=n;i++

)for

(j=0

;j) ans[i-j]

+=p[i]

*q[j]

;//這裡就表示[j+1,i]這個區間全連,而j和i+1都斷開的概率

for(i=

0;i<=n;i++

)printf

("%.12lf\n"

,ans[i]);

}

正解

#include

using

namespace std;

const

double pi=

acos(-

1);const

int maxn=

200005

;double a[maxn]

,s[maxn]

,p[maxn]

,q[maxn]

,ans[maxn]

;int n,i,j,lim=

1,l,r[maxn]

;struct node

}ans1[maxn]

,p1[maxn]

,q1[maxn]

;node operator

+(node a,node b)

node operator

*(node a,node b)

node operator

-(node a,node b)

void

fft(node a,

int lim,

int f)}}

}int

main()

for(i=

0;i<=n;i++

)reverse

(p+1

,p+1

+n);

while

(lim<=

(n+n)

)lim<<=

1,l++

;for

(int i=

1;i)r[i]

=(r[i>>1]

>>1)

|(i&1)

<<

(l-1);

for(

int i=

0;i)fft

(p1,lim,1)

;fft

(q1,lim,1)

;for

(int i=

0;i)ans1[i]

=p1[i]

*q1[i]

;fft

(ans1,lim,-1

);reverse

(ans1+

1,ans1+

1+n)

; ans1[0]

.x=0

;for

(i=0

;i<=n;i++

)printf

("%.12lf\n"

,ans1[i]

.x/lim)

;}

一道互動練習題

的做法 考慮逐位確定 對於每個位置,往後列舉有沒有位置可以使得正確位置更多,如果有,那麼有兩種情況,1是這個位置被放到了正確的位置,2是這個位置本來應該放的數被放來了 這裡的重點是我們需要區分1和2 具體的做法是記下讓這個位置答案正確位置數變大的2個位置,將其和i一起移位 這裡是手繪示意圖.即把p1...

一道sam練習題

考慮答案實際上是每個子串的出現次數的平方和.這個可以通過手玩樣例驗證.考慮廣義sam 先將所有字串建成trie,然後再在trie上bfs,建出sam.考慮fail樹 每次插入乙個新節點,會改變從這個節點開始到根的路徑上的每個節點的right集合大小.所以考慮樹剖維護這種操作,然後每乙個單詞的答案就是...

一道線段樹練習題

e9首先我們有乙個考慮列舉每個mex,計算其貢獻的想法.即有多少個區間的mex mexme x是我們當前列舉的這個值.然後我們手畫一下圖,可以發現,乙個數如果想要成為乙個區間的mex mexme x,必須要這個區間已經出現了所有比它小的數.所以可以從小到大列舉mex mexme x,然後用r rr陣...