1. 程式人生 > >FWT泛做

FWT泛做

最近複習重新學習了一下FWT,然後做了一些亂七八糟的題目。。
注:下文中的 \oplus 表示異或符號, \cap 代表按位與,

\cup 代表按位或,帶*標記的為好題集

順便提一下 O ( n 2 2 n

) O(n^2 2^n) 做子集卷積的方法,即求 H [ S ] =
i j = S , i j = 0 F [ i ] G [ j ] H[S]=\sum_{i\cup j=S,i\cap j=0}F[i]G[j]
。為了保證交起來為空集,列舉 F , G F,G 的元素個數 a , b a,b ,FWT之後只取元素個數為 a + b a+b 的值。

HDU5909 Tree Cutting

HDU

對於一個選擇方案,我們僅在深度最小的那個節點上計算。設 f [ i ] [ x ] f[i][x] 表示i號節點上,異或和為x的方案數。不難得到轉移方程:
f [ u ] [ i ] = j k f [ u ] [ j ] f [ v ] [ k ] f[u][i]=\sum_{j\oplus k}f[u][j]*f[v][k]
用fwt優化之。
時間複雜度 O ( n v log v ) O(nv\log v)

BZOJ4589 Hard Nim

BZOJ

不難想到用 f [ x ] f[x] 表示局面異或和為x的方案數,每堆石子都是等價的,所以就是n次方,快速冪即可
時間複雜度 O ( m log m log n ) O(m\log m\log n)

Codeforces 662C*

Codeforces

一道還挺有意思的題。注意到n很小,所以考慮把每一列上的數狀壓成一個整數。如果我們枚舉了一個行的異或方案,那麼每一列上就有唯一確定的權值,即要麼全選0,要麼全選1。考慮一個行的異或方案,就相當於是把每一列xor上一個數。那麼我們可以構造 a i a_i 表示有多少條列的狀態為 i i , b i b_i 表示狀態i的最小代價。

a n s ( s ) = i s = j a i b j ans(s)=\sum_{i\oplus s=j} a_ib_j
由於異或滿足交換律,那麼有
a n s ( s ) = i j = s a i b j ans(s)=\sum_{i\oplus j=s} a_ib_j
用fwt優化之,時間複雜度 O ( n 2 n ) O(n2^n)

HAOI2015 按位或

BZOJ

首先要說明的一點是我們一般用 S \overline S 來表示S的補集。
可以考慮min-max容斥,然後我們要求的就是 A [ S ] = S T P [ T ] A[S]=\sum_{S\cap T} P[T]
但是這個不好限制轉化一下,考慮到 P [ S ] = 1 \sum P[S]=1 ,那麼就有 A [ S ] = 1 T S P [ T ] A[S]=1-\sum_{T\subseteq \overline S} P[T] 。後面的做一遍高維字首和即可
時間複雜度 O ( n 2 n ) O(n2^n)

SPOJ kosare

鑑於spoj老掛,所以洛谷

F [ S ] F[S] 表示選取的盒子並起來是S的子集的方案數,那麼就可以子集反演得到恰好為S的子集的方案數。
f [ S ] f[S] 為盒子為S的子集的方案數, F [ s ] = 2 f [ S ] 1 F[s]=2^{f[S]}-1 f f 用高維字首和搞一搞即可。
由於最後只詢問一個值,可以不必做子集反演,可以 O ( n ) O(n) 地掃一遍。
時間複雜度 O ( m 2 m + n ) O(m2^m+n)

SPOJ TLE

洛谷

f [ x ] f[x] 表示考慮了前i個且以x結尾的方案數。不難得到轉移方程
f [ i ] = i j = 0 f [ j ] = j i f [ j ] f[i]=\sum_{i\cap j=0} f[j]=\sum_{j\subseteq \overline i} f[j]
每次轉移完暴力清空掉 c [ i ] c[i] 倍數的方案即可。
時間複雜度 O ( n m 2 m + n m ) O(nm2^m+nm)

hihocoder1496 尋找最大值*

hihocoder

一道還挺有意思的題目,可以考慮列舉 i j i\cap j 的值 k k ,那麼我們就需要知道最優的 i , j i,j ,那麼當然是選最大的。
因為我們難以保證 i j = k i\cap j=k ,不妨放縮條件,維護 k k 的超集中的最大和次大值。這樣顯然不會漏掉最大值,而也不可能有一個不合法的解超過最優值,因為這個不合法的解的 k k 肯定偏小,那麼必定存在一個相應的合法的解比它更大。
列舉超集用高維字首和解決。
時間複雜度 O ( v log v ) O(v\log v)