https://codeforces.ml/contest/1336/problem/E2
https://codeforces.ml/blog/entry/76099
题解非常详尽,来为自己补充一下题解。
1. 1. 1 . 长度为k k k 的线性基每种组合的出现次数都是2 n − k 2^{n-k} 2 n − k 。这第一步我就没想到。考虑前k k k 个数已经能形成2 k 2^k 2 k 个数了,那么我新添一个数,答案必然乘2 2 2 ,因为异或的数不同结果不同。
2. 2. 2 . algorithm 2 2 2 讲述了m ≤ 35 m\leq 35 m ≤ 3 5 时候的d p dp d p 。其实,用当时学Menci的线性基插入方法,他所要求的线性基已经自动消元好了。
1 2 3 4 5 6 7 8 9 10 11 inline void ins(int x) { if (!x) return; for (int i = 29; i >= 0; i--) { if (!(x >> i & 1)) continue; if (b[i]) { x ^= b[i]; continue; } rep(j, i) if (x >> j & 1) x ^= b[j]; for (int j = i + 1; j < 30; j++) if (b[j] >> i & 1) b[j] ^= x; b[i] = x; return; } }
3. 3. 3 . algorithm 3 3 3 里面初始的诀窍是非常强的。
S ( A ) S(A) S ( A ) 表示可以由线性基组成的所有数。
令a i = [ i ∈ S ( A ) ] , f i c = [ p o p c o u n t ( i ) = c ] , r e s i = [ x 0 ] a ⊕ f c a_i=[i \in S(A)],f_i^c=[popcount(i)=c],res_i=[x^0]a \oplus f^c a i = [ i ∈ S ( A ) ] , f i c = [ p o p c o u n t ( i ) = c ] , r e s i = [ x 0 ] a ⊕ f c 。
sundz说他只要会这个就能吊打tourist了。足见这个的重要。
4. 4. 4 . 下面就是研究如何快速f w t fwt f w t 和i f w t ifwt i f w t ,希望总复杂度在O ( 2 m − k ) O(2^{m-k}) O ( 2 m − k ) 。
5. 5. 5 . Lemma 1 , 2 , 3 , 4 1,2,3,4 1 , 2 , 3 , 4 都好神仙,sundz全秒了!
6. p c = 1 2 m ∑ d = 0 m 2 k q d w d c = 1 2 m − k ∑ d = 0 m q d w d c 6.p_c = \dfrac{1}{2^m}\sum\limits_{d=0}^{m} 2^k q_d w_d^c = \dfrac{1}{2^{m-k}}\sum\limits_{d=0}^{m} q_d w_d^c 6 . p c = 2 m 1 d = 0 ∑ m 2 k q d w d c = 2 m − k 1 d = 0 ∑ m q d w d c
也就是f 0 = 1 2 m ∑ i = 0 2 m − 1 f w t ( f ) i f_0=\frac{1}{2^m}\sum\limits_{i=0}^{2^m - 1}fwt(f)_i f 0 = 2 m 1 i = 0 ∑ 2 m − 1 f w t ( f ) i ,解释看下面。
这题结束了,让我们来回忆一下fwt吧!
要求我们构造一种运算,使得
F W T ( a ) i ∗ F W T ( b ) i = F W T ( c ) i FWT(a)_i*FWT(b)_i=FWT(c)_i F W T ( a ) i ∗ F W T ( b ) i = F W T ( c ) i
∑ x = 0 2 m − 1 a x f i , x ∗ ∑ y = 0 2 m − 1 b y f i , y = ∑ z = 0 2 m − 1 c z f i , z \sum\limits_{x=0}^{2^m-1}a_xf_{i,x} *\sum\limits_{y=0}^{2^m-1}b_yf_{i,y}=\sum\limits_{z=0}^{2^m-1}c_zf_{i,z} x = 0 ∑ 2 m − 1 a x f i , x ∗ y = 0 ∑ 2 m − 1 b y f i , y = z = 0 ∑ 2 m − 1 c z f i , z
f i , x ∗ f i , y = f ( i , x ⊕ y ) f_{i,x}*f_{i,y}=f(i,x \oplus y) f i , x ∗ f i , y = f ( i , x ⊕ y )
尽量让他们解的值不同。
https://www.cnblogs.com/y-clever/p/6875743.html
https://www.cnblogs.com/y-clever/p/6979925.html
也就是说,只要通过解方程,就可以构造任意位运算的fwt!
而且如果实在忘记怎么写,也可以自己手动构造,然后写成这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 void FWT_Or(int *A, int len) { if (len == 1) return; int len2 = len >> 1; FWT_Or(A, len2); FWT_Or(A + len2, len2); for (int i = 0; i < len2; ++i) A[i + len2] += A[i]; } void IFWT_Or(int *A, int len) { if (len == 1) return; int len2 = len >> 1; for (int i = 0; i < len2; ++i) A[i + len2] -= A[i]; IFWT_Or(A, len2); IFWT_Or(A + len2, len2); }
这也可以解释6 6 6 ,每层递归都是/ = 2 /=2 / = 2 。
做题的时候又忘了,再记一遍。