题目
题目大意
设 A = { 0 , 1 } A=\{0,1\} A={0,1},从 A n ( A^n ( An( 维度为 n n n,由 01 01 01组成的向量全集 ) ) )中随机选取一个。现在他想知道 n n n天中选取 n n n个线性独立向量的概率。请告诉 R o u n d g o d Roundgod Roundgod每个排列的答案,用 P ⋅ Q − 1 ( m o d 1 0 9 + 7 ) P⋅Q^{-1}(mod 10^9+7) P⋅Q−1(mod109+7)表示。其中 Q − 1 Q^{-1} Q−1是 Q Q Q模 1 0 9 + 7 10^9+7 109+7的乘法逆元。设 f n f_n fn表示维度为 n n n时的答案,最后输出 f 1 ⊕ f 2 ⊕ . . . . . . ⊕ f n f_1\oplus f_2\oplus ......\oplus f_n f1⊕f2⊕......⊕fn, ⊕ \oplus ⊕表示异或。 A n A^n An是仅包含 0 0 0和 1 1 1的 n n n维向量
分析
一看这题就知道肯定有公式可循,果断暴力,然后推公式:
在本题的条件下,不难得出以下结论:
当选取 i i i个向量时,共有 2 i 2^i 2i个向量不与选择的向量线性独立
(如果觉得难以得出请不要偷懒,老老实实看一下前文的超链接,好好理解什么是线性独立)
由上得:
在一个
n
n
n维空间里,选取
i
i
i个向量线性独立的概率就是
2
n
−
2
i
2
n
\frac{2^n-2^i}{2^n}
2n2n−2i
∴ f n = ∏ i = 0 n − 1 2 n − 2 i 2 n f_n=\prod\limits _{i=0}^{n-1}\frac{2^n-2^i}{2^n} fn=i=0∏n−12n2n−2i
这个公式看着头疼,化简一下:
原式
=
∏
i
=
0
n
−
1
2
n
−
i
−
1
2
n
−
i
=\prod\limits _{i=0}^{n-1}\frac{2^{n-i}-1}{2^{n-i}}
=i=0∏n−12n−i2n−i−1
=
∏
i
=
0
n
−
1
2
i
−
1
2
i
=\prod\limits _{i=0}^{n-1}\frac{2^i-1}{2^i}
=i=0∏n−12i2i−1
有了这个公式,我们便可以开始打表了
代码
#include <bits/stdc++.h>
const int MAXN=2e7,mod=1e9+7;
int T,n,base[MAXN],inv[MAXN],ans[MAXN];
int ksm(int x,int p)
{
int ret=1;
while(p)
{
if(p&1) ret=1ll*ret*x%mod;
x=1ll*x*x%mod;
p>>=1;
}
return ret;
}
void work()
{
base[0]=1;
for(int i=1;i<=MAXN;i++) base[i]=2ll*base[i-1]%mod;
inv[MAXN]=ksm(base[MAXN],mod-2);
for(int i=MAXN-1;i;i--) inv[i]=2ll*inv[i+1]%mod;
int x=inv[1];
ans[1]=inv[1];
for(int i=2;i<=MAXN;i++) x=1ll*x*(base[i]-1)%mod*inv[i]%mod,ans[i]=ans[i-1]^x;
}
int main()
{
work();for(scanf("%d",&T);T--;) scanf("%d",&n),printf("%d\n",ans[n]);
}
----原创文章,仅供参考