给一个 n ∗ m n*m n∗m矩阵 ( a ) i j (a)_{ij} (a)ij,行向量为 v i v_i vi, 求 ⊕ x = 0 2 k ( c o u n t ( x ) ∗ 3 x m o d ( 1 0 9 + 7 ) ) \oplus_{x=0}^{2^k}(count(x) * 3^x\space mod(10^9+7)) ⊕x=02k(count(x)∗3x mod(109+7))
其中 c o u n t ( x ) count(x) count(x)表示 1 2 m ∑ i n ∏ j m ( 1 − ( − 1 ) ∣ a i j a n d x ∣ ) \frac{1}{2^m} \sum_i^n \prod_j^m (1-(-1)^{|a_{ij} \space and \space x| }) 2m1∑in∏jm(1−(−1)∣aij and x∣), ⊕ \oplus ⊕表示异或, ∣ a ∣ |a| ∣a∣表示a的二进制中1的个数。
1 ≤ n ≤ 1 0 5 1 \leq n \leq 10^5 1≤n≤105
1 ≤ m ≤ 10 1 \leq m \leq 10 1≤m≤10
1 ≤ k ≤ 20 1 \leq k \leq 20 1≤k≤20
0 ≤ a i , j < 2 k 0 \leq a_{i,j} < 2^k 0≤ai,j<2k
考虑化简以上 c o u n t ( x ) count(x) count(x),由于 ( − 1 ) ∣ a a n d x ∣ + ∣ b a n d x ∣ = ( − 1 ) ∣ ( a ⊕ b ) a n d x ∣ (-1)^{|a\space and \space x| + |b\space and\space x|}= (-1)^{|(a \space \oplus \space b) \space and \space x|} (−1)∣a and x∣+∣b and x∣=(−1)∣(a ⊕ b) and x∣
则展开 ∏ \prod ∏后得到:
1 2 m ∑ i n ∑ S ⊆ v i ( − 1 ) s i z e ( S ) ∗ ( − 1 ) ∣ ( ⊕ j ∈ S a i j ) a n d x ∣ \frac{1}{2^m} \sum_i^n \sum_{S \subseteq {v_i}} (-1)^{size(S)} * (-1)^{|(\oplus_{\atop j \in S}a_{ij}) \space and \space x |} 2m1i∑nS⊆vi∑(−1)size(S)∗(−1)∣(⊕j∈Saij) and x∣
其中s为枚举每个行向量的二进制集合。
这里可以观察到和离散沃尔什变换相似的地方,即:
C k = ∑ i ⊕ j = k A i ∗ B j C_k=\sum_{i\oplus j=k}A_i*B_j Ck=∑i⊕j=kAi∗Bj
D W T ( A ) i = ∑ j n A j ∗ f i , j DWT(A)_i=\sum_j^nA_j*f_{i,j} DWT(A)i=∑jnAj∗fi,j
D W T ( C ) i = D W T ( A ) i ∗ D W T ( B ) i DWT(C)_i=DWT(A)_i*DWT(B)_i DWT(C)i=DWT(A)i∗DWT(B)i
⇒ f i , j ∗ f i , k = f i , j ⊕ k \Rightarrow f_{i,j}*f_{i,k}=f_{i,j\oplus k} ⇒fi,j∗fi,k=fi,j⊕k
⇒ a n d : f i , j = [ i a n d j = = i ] \Rightarrow and : f_{i,j}=[i\space and \space j == i] ⇒and:fi,j=[i and j==i]
⇒ o r : f i , j = [ i a n d j = = j ] \Rightarrow or : f_{i,j}=[i\space and \space j == j] ⇒or:fi,j=[i and j==j]
⇒ x o r : f i , j = ( − 1 ) ∣ i a n d j ∣ \Rightarrow xor : f_{i,j}= (-1)^{| i \space and \space j |} ⇒xor:fi,j=(−1)∣i and j∣
注意到 x o r xor xor的形式与上述形式完全一致,所以令
c n t x = ∑ i n ∑ S ∈ i ( − 1 ) s i z e ( S ) cnt_x = \sum_i^n \sum_{S \in i} (-1)^{size(S)} cntx=i∑nS∈i∑(−1)size(S)
其中 x = ⊕ j ∈ S a i , j x=\oplus_{\atop j \in S} a_{i,j} x=⊕j∈Sai,j,则对于 c n t cnt cnt做沃尔什变换可得:
D W T ( c n t ) x = ∑ j 2 k ∑ i n ∑ S ⊆ v i ( − 1 ) s i z e ( S ) ∗ ( − 1 ) ∣ j a n d x ∣ DWT(cnt)_x=\sum_j^{2^k}\sum_i^n\sum_{S \subseteq v_i} (-1)^{size(S)}*(-1)^{|j \ and \ x|} DWT(cnt)x=j∑2ki∑nS⊆vi∑(−1)size(S)∗(−1)∣j and x∣
由此可得:
c o u n t ( x ) = 1 2 m ∗ D W T ( c n t ) x count(x)=\frac{1}{2^m} *DWT(cnt)_x count(x)=2m1∗DWT(cnt)x
预处理 c n t x cnt_x cntx复杂度 O ( n 2 m ) O(n\ 2^m) O(n 2m), F W T FWT FWT复杂度 O ( k 2 k ) O(k\ 2^k) O(k 2k),总复杂度为 O ( n 2 m + k 2 k ) O(n \ 2^m + k \ 2^k) O(n 2m+k 2k)
// Cease to struggle and you cease to live
// D.cpp
// Created by Nickwzk
#include
using namespace std;
inline int read() {
int x = 0, ch = getchar(); bool fg = 1;
while(ch < '0' || ch > '9') { if(ch == '-') fg = 0; ch = getchar(); }
while(ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
return fg ? x : -x;
}
const int mod = 1e9 + 7;
void FWT(vector<int> &a,int n) {
for(int i = 2;i <= n; i <<= 1) {
for(int j = 0; j < n; j += i) {
for(int d = 0, w = i >> 1; d < w; d++){
int u = a[j + d], v = a[j + d + w];
a[j + d] = u + v, a[j + d + w] = u - v;
}
}
}
}
void dfs(vector<int> &cnt, const vector<int> &a, int i, int x, int p) {
if(i < a.size()) {
dfs(cnt, a, i + 1, x, p);
dfs(cnt, a, i + 1, x ^ a[i], -p);
}
else {
cnt[x] += p;
}
}
int main() {
int n, m, k;
while(~scanf("%d%d%d", &n, &m, &k)) {
auto cnt = vector<int>(1 << k, 0);
auto a = vector<int>(m);
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) a[j] = read();
dfs(cnt, a, 0, 0, 1);
}
FWT(cnt, 1 << k);
int ans = 0, pw = 1 << m, w = 1;
for(int x = 0; x < (1 << k); x++) {
ans ^= (long long)w * (cnt[x] / pw) % mod;
w = (long long)w * 3 % mod;
}
printf("%d\n", ans);
}
return 0;
}