zoukankan      html  css  js  c++  java
  • 《算法竞赛进阶指南》0x35高斯消元与线性空间 异或空间

    题目链接:https://www.acwing.com/problem/content/212/

    给定n个数,要求这些数能够异或的数中的第k小,通过求异或线性基就可以得到这些数可以异或得到的不相同的数的维数,通过这些线性基的异或便可以得到这些数的异或的所有可能的数,

    异或基中从大到小的数的最高位为1,其他数的这一位一定不是一,所以假设异或基的维数是4,则从大到小的数分别是第1000、0100、0010、0001小的数,所以只要将询问按照二进制进行分解就可以

    ,如果k的第i位是1,则取基中第dim-i个数异或到结果中去。

    注意到我们的异或基都是非零的,所以如果从给的数里面能够得到0的话,第k大就相当于基构成的数中的第k-1大,如果不能得到0的话,就从我们的基中取第k小的,就可以。

    还有一个注意点就是数据的范围,需要用unsigned long long 来进行存储,在scanf中使用的是%llu.

    #include<iostream>
    #include<cstdio>
    using namespace std;
    #define maxn 10010
    unsigned long long a[maxn];
    int main(){
        int T,n;
        cin>>T;
        int dim;
        for(int kase=1;kase<=T;kase++){
            scanf("%d",&n);
            for(int i=1;i<=n;i++)scanf("%llu",&a[i]);
            bool zero=0;//检查若干个数的异或是否可能是0 
            dim = n;//异或空间的基的维数 
            for(int i=1;i<=n;i++){//最多循环64次,基的维数便确定 
                for(int j=i+1;j<=n;j++){
                    if(a[j]>a[i])swap(a[i],a[j]);
                }
                if(a[i]==0){
                    dim=i-1;
                    zero=true;
                    break;
                }
                for(int j=63;j>=0;j--){
                    if(a[i]>>j & 1){ 
                        for(int k=1;k<=n;k++){
                            if(i!=k && (a[k]>>j & 1))a[k]^=a[i];
                        }
                        break;
                    }
                } 
            }
            
    //         cout<<dim<<endl;
            int m;
            cin>>m;
            printf("Case #%d:
    ",kase); 
            while(m--){
                unsigned long long  k,ans=0;
                scanf("%llu",&k);   
                if(zero)k--;//从这些数里面可以拼出0 
                if(k >= ((unsigned long long )1<<dim))puts("-1");
                else{
                    for(int i=dim-1;i>=0;i--){
                        if(k>>i & 1)ans^=a[dim-i];
                    }
                    printf("%llu
    ",ans);
                }
            } 
        } 
    }
  • 相关阅读:
    有个表叫杨表(上)
    Codeforces Round #698 (Div. 2) 题解 全部6题
    Leetcode 821. 字符的最短距离
    gitbook mermaid不能渲染问题
    adb命令启动app及查找系统版本号
    git库使用
    excle转html方法
    gitbook插入视频
    xcode使用技巧
    在 Mac 上的“自动操作”工作流程中使用 Shell 脚本操作
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13265979.html
Copyright © 2011-2022 走看看