2020牛客暑期多校训练营(第六场)(线性代数+找规律)

2020牛客暑期多校训练营(第六场)(线性代数+找规律)

时间限制: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 ) PQ1(mod 109+7), where Q − 1 Q^{-1} Q1 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 f1f2...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 (1T1000), 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 (1N2107) 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 2N2i个向量线性无关

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)=2n2n2i

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=1n2n2n2i

  = ∏ 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=1n2ni2ni1

  = ∏ i = 1 n 2 i − 1 2 i \,\qquad=\mathop{\prod}\limits_{i=1}^n\cfrac{2^i-1}{2^i} =i=1n2i2i1

然后就可以递推了

#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]);
}

你可能感兴趣的:(找规律,线性代数)