ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

线性基

2020-07-03 21:39:35  阅读:196  来源: 互联网

标签:int scanf ++ jj 线性 include define


 

利用高斯消元来判断向量能否被前面的向量张成

我们每次维护一个对角矩阵。执行到第 ii 步的时候,我们从高到低考虑数 a_ia​i​​ 为 11 的二进制位 jj,如果 jj 这一行的对角线已经为 11 了,那么我们不能加入,同时为了保持上三角性质,需要将第 jj 行的行向量异或到 \mathbf{a}_ia​i​​;如果 jj 这一行的对角线为 00,那么我们就可以将 \mathbf{a}_ia​i​​ 添加到这一行,同时为了维护一个对角矩阵,要先用下面的行消自己,再用自己消上面的行。

 

 

 

 

 

例题 HDU 3949 XOR

注意不存在的条件 以及能否凑出0

#pragma warning(disable:4996)

#include<iostream>
#include<algorithm>
//#include<unordered_map>
#include<fstream>
#include<iomanip>
#include<string>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<stack>
#include<sstream>
#include<cstdio>
#include<ctime>
#include<cstdlib>
#define INF 0x3f3f3f3f
#define inf 0x7FFFFFFF
#define MOD 1000000007
#define moD 1000000003
#define pii pair<string,int>
#define eps 1e-7
#define equals(a,b) (fabs(a-b)<eps)
#define bug puts("bug")
#define re  register
#define fi first
#define se second
const int maxn = 1e4 + 5;
const double Inf = 10000.0;
const double PI = acos(-1.0);
typedef  long long ll;
using namespace std;

const int max_base = 63;

int n;

ll a[maxn];
ll b[max_base+5];
vector<ll> v;

bool flag;

void cal() {
    int cnt = 0;
    memset(b, 0, sizeof b);
    for (int i = 0; i < n; ++i)
        for (int j = max_base; j >= 0; --j)
            if (a[i] >> j & 1) {
                if (b[j]) a[i] ^= b[j];
                else {
                    b[j] = a[i] , cnt++;
                    for (int k = j - 1; k >= 0; --k) if (b[k] && ((b[j] >> k) & 1)) b[j] ^= b[k];
                    for (int k = j + 1; k <= max_base; ++k) if ((b[k] >> j) & 1) b[k] ^= b[j];
                    break;
                }
            }

    v.clear();
    for (int i = 0; i <= max_base; i++) {
        if (b[i]) v.push_back(b[i]);
    }
    flag = (n != cnt);
}

ll query(ll k) {
    if (flag) k--;
    //cout << v.size() << "   xxx   " << endl;
    if (k >= (1ll<<v.size())) return -1;
    ll ans = 0;
    for (int i = 0; i < v.size(); i++) if ((k >> i) & 1) ans ^= v[i];
    return ans;
}


int main() {
    int T;
    int kase = 1;
    scanf("%d", &T);
    while (T--) {
        scanf("%d", &n);
        for (int i = 0; i < n; i++) scanf("%lld", a + i);
        cal();
        int m;
        scanf("%d", &m);
        printf("Case #%d:\n", kase++);
        while (m--) {
            ll k;
            scanf("%lld", &k);
            ll ans = query(k);
            printf("%lld\n", ans);
        }
    }
}

 

标签:int,scanf,++,jj,线性,include,define
来源: https://www.cnblogs.com/hznumqf/p/13232787.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有