A Corollary: $a\,\oplus\,b = c \rightarrow a\,\oplus\,c = b$
BZOJ 3329 Xorequ. Subtask 1
Description
Evaluate how many numbers $x$ satisfies that $x\,\oplus\,3x=2x$, for $x \le n$
Solution
Because of the Corollary above, we can get: $x\,\oplus\,2x = 3x$.
Split $3x$ into $x + 2x$, \’cause $2x = x << 1$, if there\’re $1$s on the same positions of both $x$ and $2x$\’s binary representation, the add operation ans xor operation would lead to different results! (e.g. $(1)_2 + (1)_2 = (10)_2$, while $(1)_2\,\oplus\,(1)_2 = (0)_2$).
i.e. for each legal $x$, there’s no consecutive 1s in its binary representation.
Given some points with value $c_i$ range from $0$ to $2^k - 1$, and some edges link them.
We say an edge is Safe if and only if the two points it connects have distinct values.
A kind of Virus with value $x$ is now invading the network and if a point is infected, its value changes from $c_i$ to $c_i\,\oplus\,x$. Then some of edges would be unsafe.
Evaluate the number of pairs $(A,x)$, where $A$ is a subset of points($|A| \ge 0$), and $x$ is the value of virus ranging from $0$ to $2^k-1$, if all points in $A$ were infected while no others were done so, the rest of the network remains safe.
Solution
First consider a pair of points with values $a, b$.
If $x = a\,\oplus\,b$, then this edges would turn unsafe, but lead to no effects on other points.
Thus we can put $v_i\,\oplus\,v_j$ on edge connecting $i, j$. And for each kind of edges\’ value $w_i$, we can calculate number of connected components, take any subset of these components and $w_i$ as a pair, the rest of the network wouldn’t suffer any invasion.
Use a Union-Find Set to maintain it.
Finally, for $x$ doesn’t exist in set $W$, we can take any subset of the whole graph.
Note that, refresh the parent array in $O(n)$ time will get TLE. However, use trick in code below will AC, Though it is ugly.
inline ll quick_power(ll base, ll index) { ll ret = 1; while(index) { if(index & 1) ret = (ret * base) % mod; index >>= 1; base = base * base % mod; } return ret % mod; }
intmain() { scanf("%I64d%I64d%I64d", &n, &m, &k); for(ll i = 1; i <= n; ++i) scanf("%I64d", &c[i]); for(ll i = 1; i <= m; ++i) { ll u, v; scanf("%I64d%I64d", &u, &v); ll x = (c[u] ^ c[v]); e_mp[x].push_back(edge(u,v)); } for(auto vec : e_mp) { f.clear(); unordered_set<ll> dsu; for(auto pr : vec.second) { ll fx = find(pr.frm), fy = find(pr.to); if(fx < fy) f[fy] = fx; else f[fx] = fy; dsu.insert(pr.frm); dsu.insert(pr.to); } ll single_p = dsu.size(); dsu.clear(); for(auto pr : vec.second) dsu.insert(find(min(pr.frm, pr.to))); ans = (ans + quick_power(2ll, dsu.size()+n-single_p)) % mod; } ans = ans + quick_power(2ll, n) * (quick_power(2ll, k) - e_mp.size()); ans = (ans % mod + mod) % mod; cout << ans << endl; return0; }
Codeforces 1016 D Vasya And The Matrix
Description
Consider a $n \times m$ matrix, given every line and every column\’s xor sum.
Construct a matrix satisfying the restriction if could, otherwise output No.
Solution
If we xor all given numbers together, every element in the matrix will be calculated twice, thus the result is legal if and only if it equals to $0$.
Then how to construct it?
Since the matrix is correct, we can construct it in any way we want. To make each column $j$ from $2$ to $m$ results in $b_j$, we can simply make $c_{1,j} = b_j$. Lines from $2$ to $n$ is the same. Then $c_{1,1}$ must be $a_1 \oplus b_2 \oplus \ldots \oplus b_m$. The rest of the matrix is $0$.