HDU3949 XOR

来源:互联网 发布:淘宝优站网址 编辑:程序博客网 时间:2024/05/16 05:47

题意:求出从一堆数从任意取出几个的第k小(去重)。。。

利用高斯消元求出他能组合成的数,然后用输入的数按位去比较,对于每一位选或不选,选的话就把这个数异或上去,然后就是答案了,注意如果消元后行数比原来少了,就说明可以异或出0.。

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long ll;const int MAXN=10010;ll a[MAXN];int n,m;void gauss(){    ll j;    int i,k=0;    for(j=(1ll<<62);j;j>>=1)    {        for(i=k+1;i<=n;i++)        {            if(a[i]&j)                break;        }        if(i==n+1)            continue;        swap(a[i],a[++k]);        for(i=1;i<=n;i++)        {            if((a[i]&j)&&i!=k)            {                a[i]^=a[k];            }        }    }    m=k;}void solve(){    int i,j,q;    ll x;    gauss();    int ok;    if(m==n)        ok=0;    else        ok=1;    scanf("%d",&q);    while(q--)    {        scanf("%I64d",&x);        if(ok)            x--;        if(x>=(1ll<<m))        {            printf("-1\n");            continue;        }        ll ans=0;        for(i=m;i>=1;i--)        {            if((x&1))            {                ans^=a[i];            }            x>>=1;        }        printf("%I64d\n",ans);    }}int main(){    int t,i,flag=1;    //freopen("out.txt","r",stdin);    //freopen("out1.txt","w",stdout);    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        for(i=1;i<=n;i++)            scanf("%I64d",&a[i]);        printf("Case #%d:\n",flag++);        solve();    }    return 0;}


0 0
原创粉丝点击