原题
题目描述
设,每天Roundgod从(即维度为n,每一位由01组成的所有向量的集合)中随机选择一个二进制向量。现在他想知道n天中选取n个线性独立向量的概率。答案的输出格式同上题,模数为。
设表示n的答案,最后输出,表示异或。
线性独立
对于问题B,A^n是仅包含0和1的n维向量。
样例
输入
3
1
2
3
输出
500000004
194473671
861464136
思路
由于这n个向量线性独立,所以张成了(N维)满秩空间,每一个向量都不属于之前的空间,总共有
n 个向量。
为了讨论其中的规律,我们可以设有
等向量
若
,则
这两个向量与
有关。
若
,则
这个向量与
有关。
若
,则
这两个向量与
有关……
由此可以推出对于每个i,会有
i 个向量线性相关,所以有
n -
i个向量线性独立(无关)。
因此,可得:
所以,只需照着上面打一个
大小的表,最后输出即可。如果还是不懂,请看代码。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e7,mod=1e9+7;
int t,n,x,mul[maxn],inv[maxn],ans[maxn];
int ksm(int a,int b)
{
int cnt=1;
while(b)
{
if(b&1)cnt=1ll*cnt*a%mod;
a=1ll*a*a%mod;
b>>=1;
}
return cnt;
}
int main()
{
mul[0]=1;
for(int i=1;i<=maxn;i++) mul[i]=2ll*mul[i-1]%mod;
inv[maxn]=ksm(mul[maxn],mod-2);
for(int i=maxn-1;i;i--) inv[i]=2ll*inv[i+1]%mod;
x=inv[1];ans[1]=inv[1];
for(int i=2;i<=maxn;i++) x=1ll*x*(mul[i]-1)%mod*inv[i]%mod,ans[i]=ans[i-1]^x;
for(scanf("%d",&t);t--;)scanf("%d",&n),printf("%d\n",ans[n]);
}