场上没过非常可惜,读题时间太久
随机取n个n维01向量,求这n个向量线性无关的概率fn,输出f1^f2^...fn
题解:首先,n维01向量共有2n种,0向量与任何向量线性相关,则第一次取有2n-1种取法,概率为(2n-1)/(2n)第二次取要去掉0向量和第一次的向量,共2n-2种取法,第三次取去掉0向量、第1次和第2次取的向量能够组合的所有向量,共2n-4种取法,以此类推。
可以推出fn=[(2n-1)/2n]*fn-1=[1-1/2n]*fn-1
考虑到1/2的逆元inv2=5e8+4,则1/2n=(1/2n-1)*inv2。则可以O(n)做出。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<algorithm> 4 #include<cstring> 5 #include<queue> 6 using namespace std; 7 #define ll long long 8 ll const mod=1e9+7; 9 ll const inv2=5e8+4; 10 int const N=2e7+5; 11 ll f[N]; 12 int main(){ 13 f[1]=inv2; 14 ll temp=inv2; 15 for (int i=2;i<N;i++){ 16 temp=(temp*inv2)%mod; 17 f[i]=(f[i-1]*(1+mod-temp))%mod; 18 } 19 for (int i=2;i<N;i++) 20 f[i]=f[i-1]^f[i]; 21 int t; 22 scanf("%d",&t); 23 while (t--){ 24 int n; 25 scanf("%d",&n); 26 printf("%lld\n",f[n]); 27 } 28 return 0; 29 }