Title Link: Moamen and XOR
General meaning
Given n and k, let you construct a length of n n Sequence a [], each element less than 2 k 2^k 2k.
Requirement sequence satisfied a 1 a_1 a1 & a 2 a_2 a2 & a 3 a_3 a3 & ... & a n a_n an ≥ a 1 a_1 a1 ⊕ a 2 a_2 a2 ⊕ a 3 a_3 a3 ⊕ ... ⊕ a n a_n an
Q: there are two sequences that meet the requirements
Problem solving ideas
thinking
The numbers mentioned below are in binary form!!! For simplicity, remember a n d and and is the result on the left of the original formula, x o r xor xor is the result on the right
We first default that all bits are 1, then there must be and == xor
Next, let's consider reducing the number Since the change of the high bit will directly affect the size of the number, we consider the case of the highest bit:
The highest order is all 1:
If n is an odd number, it indicates
a
n
d
and
And , and
x
o
r
xor
The highest order of xor , is 1, which is equal. We need to continue to analyze the second highest order
At this time, the answer contribution = the answer contribution of the second highest position
If n is an even number, it indicates
a
n
d
and
The highest bit of and is 1, and
x
o
r
xor
The highest bit of xor , is 0, which is when and is greater than xor At this time, other bits can be arranged arbitrarily, all satisfying and > xor
At this time, the answer contribution = the total number of fully arranged schemes in other positions
Suppose it's the second i i i bit, then there is j = i − 1 j = i - 1 j=i − 1 can be fully arranged, and each position has two values of 01, so one number has two values in common 2 j 2^j In 2j cases, there are n numbers in total, so the total number of schemes is: ( 2 j ) n (2^j)^n (2j)n
The highest bit is not all 1:
We consider changing part 1 to bit 0 At this time, the highest bit of and must be 0, so the highest bit of xor must also be 0, then there must be an even number of 1 at the highest bit
If n is an odd number, we can select {1, 3, 5,..., n} positions so that their highest order becomes 0
If n is an even number, we can select {2, 4, 6,..., n} positions so that their highest position becomes 0
The way to select these locations is:
Odd: s u m = C n 1 + C n 3 + . . . + C n n sum = C_n^1 + C_n^3 + ... + C_n^n sum=Cn1+Cn3+...+Cnn
even numbers: s u m = C n 2 + C n 4 + . . . + C n n sum = C_n^2 + C_n^4 + ... + C_n^n sum=Cn2+Cn4+...+Cnn
At this time, the answer contribution = sum * the scheme contribution of the second highest order
So far, we have analyzed all the situations. When analyzing the other bits, we think that there is no similar analysis for the high bits We found that it should be discussed in categories That is, it is classified according to the parity of n
Let dp[], dp[i] represent the contribution of bit I
When n is odd: d p [ i ] = d p [ i − 1 ] ∗ ( 1 + s u m ) dp[i] = dp[i - 1] * (1 + sum) dp[i]=dp[i − 1] * (1+sum) where 1 is the scheme when bit I is all 1 and sum is the scheme when bit I is not all 1
When n is even: d p [ i ] = d p [ i − 1 ] ∗ ( ( 2 i − 1 ) n + s u m ) dp[i] = dp[i - 1] * ((2^{i-1})^{n} + sum) dp[i]=dp[i − 1] * ((2i − 1)n+sum) where ( 2 i − 1 ) n (2^{i-1})^{n} (2i − 1)n is the scheme when the ith bit is all 1, and sum is the scheme when the ith bit is not all 1
If you have any questions about this blog, please leave a message in the comment area and I will reply to you tonight
AC code
#include <bits/stdc++.h> #define rep(i, n) for (int i = 1; i <= (n); ++i) using namespace std; typedef long long ll; const int N = 2E5 + 10, mod = 1E9 + 7; int fpow(int a, int b) { //Counting ll res = 1; a %= mod; while (b) { if (b & 1) res = res * a % mod; b >>= 1; a = 1ll * a * a % mod; } return res; } /* Combinatorial mathematics */ int num[N], innum[N]; void init(int n = N - 5) { num[0] = innum[0] = 1; for (int i = 1; i <= n; ++i) { num[i] = 1ll * num[i - 1] * i % mod; innum[i] = 1ll * innum[i - 1] * fpow(i, mod - 2) % mod; //Inverse element } } int C(int a, int b) { return 1ll * num[a] * innum[a - b] % mod * innum[b] % mod; } /* Processing combination prefix */ int calcodd(int n) { ll res = 0; for (int i = 1; i <= n; i += 2) res = (res + C(n, i)) % mod; return res; } int calceven(int n) { ll res = 0; for (int i = 2; i <= n; i += 2) res = (res + C(n, i)) % mod; return res; } int dp[N]; int main() { init(); // It can't be true? Did you write combinatorics and forget to call init()? int t; cin >> t; while (t--) { int n, k; scanf("%d %d", &n, &k); dp[0] = 1; if (n & 1) { int sum = calcodd(n); for (int i = 1; i <= k; ++i) { dp[i] = 1ll * dp[i - 1] * (1 + sum) % mod; } } else { int sum = calceven(n); for (int i = 1; i <= k; ++i) { dp[i] = 1ll * dp[i - 1] * sum % mod; dp[i] = (dp[i] + fpow(fpow(2, i - 1), n)) % mod; } } printf("%d\n", dp[k]); } return 0; }