线性代数 向量 秩 2020牛客暑期多校训练营(第六场)Binary Vector

线性代数 向量 秩 2020牛客暑期多校训练营(第六场)Binary Vector

题目大意:

给出一个 n * n 的 01 矩阵,求满秩的概率

题解:

对于第一个只要不全为0即可,方案是:\(2^n-1\)

对于第二个只要不全为0,且不被第一个表示即可,方案数:\(2^n-2\)

对于第三个只要不全为0,并且不被第一个第二个表示即可,方案数:\(2^n-4\)

...

对于最后一个的方案数:\(2^n- 2^{n-1}\)

直接相乘:$\prod_{i=0}^{i=n-1} (2^n-2^i) $

每一个的所有总方案数都是 \(2^n\) ,相乘得 \(2^{n^2}\)

所以最后的概率是 :\(\frac{\prod_{i=0}^{i=n-1} (2^n-2^i)}{2^{n^2}}\)

但是这个式子要进行优化,才可以得出解:

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
#define debug(x) printf("debug:%s=%lld\n",#x,x);
using namespace std;
typedef long long ll;
const int maxn = 2e7+10;
const int mod = 1e9+7;
ll f[maxn],ans[maxn];
void init(){
    ll inv = 500000004;
    f[1] = ans[1] = inv;
    ll up = 2,down = inv;
    for(int i=2;i<maxn;i++){
        up=up*2%mod;
        down = down*inv%mod;
        f[i]=(up-1+mod)%mod*down%mod*f[i-1]%mod;
        ans[i]=f[i]^ans[i-1];
    }
}

int main(){
    init();
    int t;
    scanf("%d",&t);
    while(t--){
        int n;
        scanf("%d",&n);
        printf("%lld\n",ans[n]);
    }
}

猜你喜欢

转载自www.cnblogs.com/EchoZQN/p/13405975.html