B.Binary Vector
题目链接-B.Binary Vector
题目大意
每天
R
o
u
n
d
g
o
d
Roundgod
Roundgod从维度为n,每一位由01组成的所有向量的集合中随机选择一个二进制向量,现在他想知道
n
n
n天中选取
n
n
n个线性独立向量的概率,答案如果是
P
Q
(
P
,
Q
互
质
)
\frac{P}{Q}(P,Q互质)
QP(P,Q互质),就输出
P
⋅
Q
−
1
(
mod
1
0
9
+
7
)
P \cdot Q^{-1} (\textrm{mod}\ 10^9+7 )
P⋅Q−1(mod 109+7)
解题思路
- 通过观察样例和打表可以得出当 i > 1 i>1 i>1时,假设 f ( i − 1 ) = x y f(i-1)=\frac{x}{y} f(i−1)=yx,则 f ( i ) = x ( 2 x + 1 ) y × 2 y = f ( i − 1 ) 2 i − 1 2 i f(i)=\frac{x(2x+1)}{y×2y}=f(i-1)\frac{2^i-1}{2^i} f(i)=y×2yx(2x+1)=f(i−1)2i2i−1,可以发现答案每次就是乘上一个 2 i − 1 2 i \frac{2^i-1}{2^i} 2i2i−1,而观察 2 i − 1 2 i \frac{2^i-1}{2^i} 2i2i−1发现每次要多除一次 2 2 2,那就多乘一次 2 2 2的逆元 i n v ( 2 ) inv(2) inv(2)
- 所以我们只需要一个复杂度为 O ( n ) O(n) O(n)的递推,在这个过程维护 2 2 2的幂与 i n v ( 2 ) inv(2) inv(2)的幂就行了
- 另: 500000004 500000004 500000004是 2 2 2的逆元
- 具体操作见代码
附上代码
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define lowbit(x) (x &(-x))
#define endl '\n'
using namespace std;
const int INF=0x3f3f3f3f;
const int dir[4][2]={-1,0,1,0,0,-1,0,1};
const double PI=acos(-1.0);
const double e=exp(1.0);
const double eps=1e-10;
const int M=1e9+7;
const int N=2e7+10;
typedef long long ll;
typedef pair<int,int> PII;
typedef unsigned long long ull;
inline void read(int &x){
char t=getchar();
while(!isdigit(t)) t=getchar();
for(x=t^48,t=getchar();isdigit(t);t=getchar()) x=x*10+(t^48);
}
ll ans[N],x=5e8+4,y=5e8+4;
int main(){
int t;
read(t);
ans[1]=x;
for(int i=2;i<=2e7;i++){
x=x*y%M;
ans[i]=(ans[i-1]-ans[i-1]*x)%M+M;
}
for(int i=2;i<=2e7;i++)
ans[i]^=ans[i-1];
while(t--){
int n;
read(n);
printf("%lld\n",ans[n]);
}
return 0;
}