微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

hdu3949:XOR

Problem Description
XOR is a kind of bit operator,we define that as follow: for two binary base number A and B,let C=A XOR B,then for each bit of C,we can get its value by check the digit of corresponding position in A and B. And for each digit,1 XOR 1 = 0,1 XOR 0 = 1,0 XOR 1 = 1,0 XOR 0 = 0. And we simply write this operator as ^,like 3 ^ 1 = 2,4 ^ 3 = 7. XOR is an amazing operator and this is a question about XOR. We can choose several numbers and do XOR operatorion to them one by one,then we get another number. For example,if we choose 2,3 and 4,we can get 2^3^4=5. Now,you are given N numbers,and you can choose some of them(even a single number) to do XOR on them,and you can get many different numbers. Now I want you tell me which number is the K-th smallest number among them.
 
Input
First line of the input is a single integer T(T<=30),indicates there are T test cases.
For each test case,the first line is an integer N(1<=N<=10000),the number of numbers below. The second line contains N integers (each number is between 1 and 10^18). The third line is a number Q(1<=Q<=10000),the number of queries. The fourth line contains Q numbers(each number is between 1 and 10^18) K1,K2,......KQ.
 
Output
For each test case,first output Case #C: in a single line,C means the number of the test case which is from 1 to T. Then for each query,you should output a single line contains the Ki-th smallest number in them,if there are less than Ki different numbers,output -1.
 
Sample Input
2 2 1 2 4 1 2 3 4 3 1 2 3 5 1 2 3 4 5
 
Sample Output
Case #1: 1 2 3 -1 Case #2: 0 1 2 3 -1
Hint
If you choose a single number,the result you get is the number you choose. Using long long instead of int because of the result may exceed 2^31-1.
 
 
好玄学啊这玩意儿
首先判一下边界:如果能得到0,就特殊处理答案,因为题目不支持自己异或自己这种操作
高斯消元,边消元边排序,如果得到了0,就说明可以通过异或得到这个数,那么这个数就是无意义的
那么剩下来的肯定对于二进制中的某一位,只有他为1其他都为0,要不然会被消掉
所以他们的特殊位也是从大到小排序的,那么感性的yy一下:
当前的a1,异或了之后的a2一定更大,然后数学归纳一下
就可以按照排名来取a异或,得出答案
代码如下:
//MT_LI
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef long long ll;
ll a[110000];
int n,m;
int main()
{
    int T,Case=0;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
        bool bk=0;int t=n;
        for(int i=1;i<=n;i++)
        {
            for(int j=i+1;j<=n;j++)
                if(a[j]>a[i])
                    swap(a[j],a[i]);
            if(a[i]==0){bk=1;t=i-1;break;}
            for(int k=63;k>=0;k--)
                if(a[i]>>k&1)
                {
                    for(int j=1;j<=n;j++)    
                        if(i!=j&&a[j]>>k&1)
                            a[j]^=a[i];
                    break;
                }
        }
        scanf("%d",&m);
        printf("Case #%d:\n",++Case);
        while(m--)
        {
            ll x,ans=0ll;
            scanf("%lld",&x);
            if(bk==true)x--;
            if(x>1ll<<t)printf("-1\n");
            else
            {
                for(int i=t-1;i>=0;i--)
                    if(x>>i&1)
                        ans^=a[t-i];
                printf("%lld\n",ans);
            }
        }
    }
    return 0;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐