时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
judge:牛客
Roundgod is obsessive about linear algebra. Let A = { 0 , 1 } A=\{0,1\} A={0,1}, everyday she will generate a binary vector randomly in A n A^n An. Now she wonders the probability of generating n n n linearly independent vectors in the next n n n days modulo 1 0 9 + 7 10^9+7 109+7. Formally, it can be proved that the answer has the form of P Q \frac{P}{Q} QP, where P P P and Q Q Q are coprime and Q Q Q is not a multiple of 1 0 9 + 7 10^9+7 109+7. The answer modulo 1 0 9 + 7 10^9+7 109+7 thus means P ⋅ Q − 1 ( mod 1 0 9 + 7 ) P \cdot Q^{-1} (\textrm{mod}\ 10^9+7 ) P⋅Q−1(mod 109+7), where Q − 1 Q^{-1} Q−1 is the multiplicative inverse of 1 0 9 + 7 10^9+7 109+7.
Wcy thinks the problem too easy. Let the answer of n n n be f n f_n fn, she wants to know f 1 ⊕ f 2 ⊕ . . . ⊕ f N f_1\oplus f_2\oplus ...\oplus f_N f1⊕f2⊕...⊕fN, where ⊕ \oplus ⊕ denotes bitwise exclusive or operation.
Note that when adding up two vectors, the components are modulo 2 2 2.
The input contains multiple test cases. The first line of input contains one integer T ( 1 ≤ T ≤ 1000 ) T\ (1\le T\le 1000 ) T (1≤T≤1000), denoting the number of test cases.
In the following T T T lines, each line contains an integer N ( 1 ≤ N ≤ 2 ∗ 1 0 7 ) N\ (1\le N\le 2*10^7 ) N (1≤N≤2∗107) describing one test case.
For each test case, output one integer indicating the answer.
3
1
2
3
500000004
194473671
861464136
f ( 1 ) = 1 2 f ( 2 ) = 3 8 f ( 3 ) = 21 64 f(1)=\frac{1}{2}\\ f(2)=\frac{3}{8}\\ f(3)=\frac{21}{64} f(1)=21f(2)=83f(3)=6421
设 A A A={0,1},每天Roundgod从 A n {A^n} An(即维度为n,每一位由01组成的所有向量的集合)中随机选择一个二进制向量。现在他想知道n天中选取n个线性独立向量的概率。
设 f n f_n fn表示n的答案,最后输出 ,表示异或。
线性独立是什么?(其实就是任意一个向量不能通过其他两个的“加减”运算得到)
由于这 n n n个向量线性无关所以它们张成了满秩空间( N N N维)
每一个向量都不属于之前的空间总共 2 N 2^N 2N 个向量
当 N = 1 N=1 N=1时,设取到向量 a ⃗ ~\vec{a} a共有2个向量与它线性相关: a ⃗ ~\vec{a} a
当 N = 2 N=2 N=2时,设取到向量 a ⃗ b ⃗ ~\vec{a}~\vec{b} a b共有4个向量与它们线性相关: a ⃗ ~\vec{a} a, b ⃗ ~\vec{b} b, a ⃗ + b ⃗ ~\vec{a}+\vec{b} a+b, 0 ⃗ ~\vec{0} 0
当 N = 3 N=3 N=3时,设取到向量 a ⃗ b ⃗ c ⃗ ~\vec{a}~\vec{b}~\vec{c} a b c共有8个向量与它们线性相关: a ⃗ ~\vec{a} a, b ⃗ ~\vec{b} b, c ⃗ ~\vec{c} c, a ⃗ + b ⃗ ~\vec{a}+\vec{b} a+b, b ⃗ + c ⃗ ~\vec{b}+\vec{c} b+c, a ⃗ + c ⃗ ~\vec{a}+\vec{c} a+c, a ⃗ + b ⃗ + c ⃗ ~\vec{a}+\vec{b}+\vec{c} a+b+c, 0 ⃗ ~\vec{0} 0
…
以此类推,当 N = i N=i N=i时,有 2 i 2^i 2i个向量线性相关就有 2 N − 2 i 2^N−2^i 2N−2i个向量线性无关
P ( l i n e a r i n d e p e n d e n t ) = 2 n − 2 i 2 n P(linear~independent)=\cfrac{2^n-2^i}{2^n} P(linear independent)=2n2n−2i
f ( n ) = ∏ i = 1 n 2 n − 2 i 2 n f(n)=\mathop{\prod}\limits_{i=1}^n\cfrac{2^n-2^i}{2^n} f(n)=i=1∏n2n2n−2i
= ∏ i = 1 n 2 n − i − 1 2 n − i \,\qquad=\mathop{\prod}\limits_{i=1}^n\cfrac{2^{n-i}-1}{2^{n-i}} =i=1∏n2n−i2n−i−1
= ∏ i = 1 n 2 i − 1 2 i \,\qquad=\mathop{\prod}\limits_{i=1}^n\cfrac{2^i-1}{2^i} =i=1∏n2i2i−1
然后就可以递推了
#include
const int N = 2e7, mod = 1e9 + 7;
int T, n, mul[N], inv[N], ans[N];
int ksm(int a, int b) {
int r = 1;
while (b) {
if (b & 1) r = 1ll * r * a % mod;
a = 1ll * a * a % mod, b >>= 1;
}
return r;
}
int main() {
mul[0] = 1;
for (int i = 1; i <= N; i++) mul[i] = 2ll * mul[i - 1] % mod;
inv[N] = ksm(mul[N], mod - 2);
for (int i = N - 1; i; i--) inv[i] = 2ll * inv[i + 1] % mod;
int x = inv[1];
ans[1] = inv[1];
for (int i = 2; i <= N; i++)
x = 1ll * x * (mul[i] - 1) % mod * inv[i] % mod,
ans[i] = ans[i - 1] ^ x;
scanf("%d", &T);
while (T--) scanf("%d", &n), printf("%d\n", ans[n]);
}