• hdu3949XOR(线性基)


    传送门

    不知道线性基是什么东西的可以看看蒟蒻的总结

    题目大意:求一堆数字能异或出的第$k$大的数是多少

    线性基求第k大好珂怕……

    据大佬们说就是把$k$给二进制拆分,如果$k$的第$i$位为1,那么$ans^=b[i]$

    然后就是注意矩阵得消成对角矩阵而不是上三角矩阵……

    这样的话$1$只会出现在对角线上

    记$cnt$为对角线上有多少个$1$

    显然能获得的异或值总共有$1<<cnt$个(包括0)

    然后注意,如果$cnt!=n$,那么这一堆数字就是线性相关的,可以异或出0

    否则的话说明这一堆数字线性无关,无法异或出0,那么得把$k++$(因为我们这里的$k$是默认能取到0的)

    然后剩下的细节看代码好了

     1 //minamoto
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstring>
     5 #define ll long long
     6 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     7 char buf[1<<21],*p1=buf,*p2=buf;
     8 inline ll read(){
     9     #define num ch-'0'
    10     char ch;bool flag=0;ll res;
    11     while(!isdigit(ch=getc()))
    12     (ch=='-')&&(flag=true);
    13     for(res=num;isdigit(ch=getc());res=res*10+num);
    14     (flag)&&(res=-res);
    15     #undef num
    16     return res;
    17 }
    18 const int N=1e5+5;
    19 int n,m,k;ll a[N],b[105];
    20 void init(){
    21     for(int i=1;i<=n;++i)
    22     for(int j=63;j>=0;--j){
    23         if(a[i]>>j&1){
    24             if(b[j]) a[i]^=b[j];
    25             else{
    26                 b[j]=a[i];
    27                 for(int k=j-1;k>=0;--k)
    28                 if(b[k]&&(b[j]>>k&1)) b[j]^=b[k];
    29                 for(int k=j+1;k<=63;++k)
    30                 if(b[k]>>j&1) b[k]^=b[j];
    31                 break;
    32             }
    33         }
    34     }
    35 }
    36 int main(){
    37 //    freopen("testdata.in","r",stdin);
    38     int T=read();
    39     for(int cas=1;cas<=T;++cas){
    40         memset(b,0,sizeof(b));n=read();
    41         for(int i=1;i<=n;++i) a[i]=read();
    42         init();
    43         int cnt=0;
    44         for(int i=0;i<=63;++i)
    45         if(b[i]) ++cnt;
    46         m=read();
    47         printf("Case #%d:
    ",cas);
    48         while(m--){
    49             ll x=read();
    50             if(cnt==n) ++x;
    51             if(x>(1ll<<cnt)){puts("-1");continue;}
    52             ll ans=0;
    53             int tmp=cnt;
    54             for(int i=63;i>=0;--i){
    55                 if(b[i]){
    56                     ll now=(1ll<<(tmp-1));
    57                     if(x>now) x-=now,ans^=b[i];
    58                     --tmp;
    59                 }
    60             }
    61             printf("%lld
    ",ans);
    62         }
    63     }
    64     return 0;
    65 }
  • 相关阅读:
    一、NHibernate 使用配置与实现简单查询
    NHibernate学习步骤
    sql2008转成2005的解决办法
    二、使用NHibernate对数据库实现增、删、改、查操作
    FusionCharts 点击事件 新页面
    [分享]NHibernate视频教程
    FusionCharts Free使用文档教程第五章FusionCharts Free使用dataXML加载数据
    职业规划
    网页生成pdf文件
    FusionCharts Free使用文档教程第四章FusionCharts Free使用JavaScript加载图形
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9714991.html
Copyright © 2020-2023  润新知