1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include <vector> #include <utility> template <typename T>void FWT (std::vector<T>& f, T m00, T m01, T m10, T m11) { const int N = f.size (); for (int k = 1 ; k < N; k <<= 1 ) { for (int j = 0 ; j < N; j += (k << 1 )) { for (int i = 0 ; i < k; i++) { T& u = f[i + j]; T& v = f[i + j + k]; std::tie (u, v) = std::pair ( m00 * u + m01 * v, m10 * u + m11 * v ); } } } } template <typename T> void FWT_OR (std::vector<T>& f) { FWT <T>(f, 1 , 0 , 1 , 1 ); }template <typename T> void IFWT_OR (std::vector<T>& f) { FWT <T>(f, 1 , 0 , -1 , 1 ); }template <typename T> void FWT_AND (std::vector<T>& f) { FWT <T>(f, 1 , 1 , 0 , 1 ); }template <typename T> void IFWT_AND (std::vector<T>& f) { FWT <T>(f, 1 , -1 , 0 , 1 ); }template <typename T> void FWT_XOR (std::vector<T>& f) { FWT <T>(f, 1 , 1 , 1 , -1 ); }template <typename T> void IFWT_XOR (std::vector<T>& f) { FWT_XOR (f); const int N = f.size (); T invN = 1 / static_cast <T>(N); for (int i = 0 ; i < N; i++) { f[i] *= invN; } }
节点是所有 N N N 位二进制数。若 u ∧ v = 0 u \land v = 0 u ∧ v = 0 ,则存在边 u → v u \to v u → v 。 游走的特征值:沿途所有节点的按位异或和。 游走的分数:设起点 v v v ,则为 C v C_{v} C v 。 考虑所有长度为 K K K 的游走,对每个特征值 s s s 统计 f s = ∑ s C v f_{s}=\sum_{s} C_{v} f s = ∑ s C v 。 N ⩽ 20 , K ⩽ 1 0 18 N \leqslant 20, K \leqslant 10^{18} N ⩽ 2 0 , K ⩽ 1 0 1 8 。每位独立,拆成 N N N 个彼此独立的 01 序列,相邻两个节点不允许同时为 1。
对第 i i i 位,利用矩阵计算起点 v i v_{i} v i ,特征值 s i s_{i} s i 的方案数 M s i , v i M_{s_{i},v_{i}} M s i , v i 。复杂度 O ( 4 3 log K ) \mathcal{O}(4^{3}\log K) O ( 4 3 log K ) 。
答案是每位贡献之积,
f s = ∑ v = 0 2 N − 1 C v ∏ i = 0 N − 1 M s i , v i f_{s} = \sum_{v=0}^{2^N-1} C_{v} \prod_{i=0}^{N-1} M_{s_i, v_i} f s = v = 0 ∑ 2 N − 1 C v i = 0 ∏ N − 1 M s i , v i
这本质上是一个矩阵乘法 f = T C f = T C f = T C 。
矩阵 T T T 达到 2 20 × 2 20 2^{20} \times 2^{20} 2 2 0 × 2 2 0 ,难以直接计算,但考虑到 s s s 和 v v v 的每一位二进制是完全独立的,矩阵 T T T 实际上是由 N N N 个相同的 2 × 2 2 \times 2 2 × 2 基础矩阵通过 Kronecker 乘积构成。
( f 0 f 1 ) ← ( M 0 , 0 M 0 , 1 M 1 , 0 M 1 , 1 ) ( f 0 f 1 ) \begin{pmatrix} f_0 \\ f_1 \end{pmatrix} \gets \begin{pmatrix} M_{0,0} & M_{0,1} \\ M_{1,0} & M_{1,1} \end{pmatrix} \begin{pmatrix} f_0 \\ f_1 \end{pmatrix} ( f 0 f 1 ) ← ( M 0 , 0 M 1 , 0 M 0 , 1 M 1 , 1 ) ( f 0 f 1 )