数学基础II 线性基 高斯消元 中国剩余定理 BSGS

线性基

线性基可以“存储”一个数的集合的所有子集的异或和。它支持查询最大/最小/第k小子集异或和或一个异或和是否存在。线性基可以插入,但不能删除。

long long a[55], s[55], top;

void insert(long long x) {
    for(int i = 62; i >= 0; i--) if(x&(1ll<<i)) {
        if(!a[i]) {
            a[i] = x;
            return;
        }
        x ^= a[i];
    }
}

int exist(long long x) {
    for(int i = 62; i >= 0; i--) if(x&(1ll<<i)) {
        x ^= a[i];
        if(!x) return 1;
    }
    return 0;
}

long long query_max() {
    long long ans = 0;
    for(int i = 62; i >= 0; i--) if((ans^a[i]) > ans) ans ^= a[i];
    return ans;
}

long long query_min() {
    for(int i = 0; i <= 62; i++) if(a[i]) return a[i];
    return -1;
}

long long kth(int k) {
    for(int i = 62; i >= 0; i--) for(int j = i-1; j >= 0; j--) if(a[i]&(1ll<<j)) a[i] ^= a[j];
    top = 0;
    for(int i = 0; i <= 62; i++) if(a[i]) s[top++] = a[i];
    long long ans = 0;
    for(int i = 62; i >= 0; i--) if(k&(1ll<<i)) ans ^= a[i];
    return ans;
}

矩阵

高斯消元

几乎就是手动消元的过程。

void gauss() {
    for(int i = 0; i < n; i++) {
        int r = i;
        for(int j = i+1; j < n; j++) if(fabs(a[j][i]) > fabs(a[r][i])) r = j;
        for(int j = 0; j <= n; j++) swap(a[i][j], a[r][j]);
        for(int j = n; j >= i; j--) for(int k = i+1; k < n; k++) a[k][j] -= a[k][i]/a[i][i] * a[i][j]; // 提高精度
    }
    for(int i = n-1; i >= 0; i--) { // 回代
        for(int j = i+1; j < n; j++) a[i][n] -= a[j][n] * a[i][j];
        a[i][n] /= a[i][i];
    }
}

矩阵的逆

用高斯消元。

中国剩余定理

中国剩余定理用于求解形如 x b i ( mod m i ) 的一组方程。
设有 n 个方程,我们计算另外“特殊的” n 个方程组的解。第 p 个“特殊方程组”形如 x b p ( mod m p ) x b i ( mod m i ) , i p
可以轻易地用扩展欧几里得求出这些“特殊方程组”的解。
则原方程组的解,就等于每一组“特殊方程组”的解乘以其序号对应的系数的和,对 i = 1 n m i 取模。

int china() {
    int M = 1, ans = 0;
    for(int i = 0; i < n; i++) M *= m[i];
    for(int i = 0; i < n; i++) {
        int d, y;
        exgcd(m[i], M/m[i], d, d, y);
        ans = (ans + y*(M/m[i])*a[i]) % M;
    }
    return ans;
}

Upd on 2018.7.20:
M = i = 1 n m i M i = M m i
x = i = 1 n a i i n v ( M i , m i ) M i ( mod M )

大步小步算法

大步小步算法用于解方程 a x b ( mod n ) ,时间复杂度为 O ( n )
根据欧拉定理,如果有解,则解一定在 [ 0 , n ) 中。
BSGS的基本思想是先求出 e i = a i mod n ( i < n ) ,全部存在哈希表中。对于之后的 i ,只需检查是否有 e i = a j m b ( 0 < j < n ) 即可。
这体现了一种分组的思想。

Miller-Rabin素数测试

Miller-Rabin算法是基于费马小定理的。
这个Miller_Rabin没有用二次探测定理,但不保证会出错。

int miller_rabin(int x) {
    if(x == 2) return 1;
    for(int i = 0; i < 10; i++) {
        int a = rand() % (x-2) + 2;
        if(qpow(a, x, x) != a) return 0;
    }
    return 1;
}

Pollard Rho

明天

猜你喜欢

转载自blog.csdn.net/myjs999/article/details/79264967