xor序列 (线性基)

版权声明:小白一个,欢迎各位指错。 https://blog.csdn.net/qq_36424540/article/details/82717890

链接:https://www.nowcoder.com/acm/contest/180/D
来源:牛客网
 

题目描述

小a有n个数,他提出了一个很有意思的问题:他想知道对于任意的x, y,能否将x与这n个数中的任意多个数异或任意多次后变为y

输入描述:

第一行为一个整数n,表示元素个数
第二行一行包含n个整数,分别代表序列中的元素
第三行为一个整数Q,表示询问次数
接下来Q行,每行两个数x,y,含义如题所示

输出描述:

输出Q行,若x可以变换为y,输出“YES”,否则输出“NO”

示例1

输入

复制

5
1 2 3 4 5
3
6 7 
2 1
3 8

输出

复制

YES
YES
NO

说明

对于(6,7)来说,6可以先和3异或,再和2异或
对于(2,1)来说,2可以和3异或
对于(3,8)来说,3不论如何都不能变换为8

备注:

对于100%的数据,n,Q<=105
保证所有运算均在int范围内
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;

#define rep(i,a,b) for(int i=a;i<b;++i)
#define per(i,a,b) for(int i=b-1;i>=a;--i)


const int N=1e5+10;

LL a[N],p[70];

void inser(int n){
    for(int i=1; i<=n; i++) {
        for(int j=62; j>=0; j--){
            if((a[i]>>j)&1){
              if(!p[j]) {
                 p[j]=a[i];    //选入线性基中
                 break;
              }
              a[i]^=p[j];
            }
        }
    }
}


int main()
{
    int n;
    scanf("%d",&n);
    rep(i,1,n+1) {
        scanf("%lld",&a[i]);
    }
    inser(n);

    int m;
    scanf("%d",&m);
    while(m--){
        LL x,y;
        scanf("%lld %lld",&x,&y);
        LL tmp=x^y;
        for(int j=62;j>=0;--j){
            if((tmp>>j)&1){
                tmp=tmp^p[j];
            }
        }
        if(tmp)printf("NO\n");
        else printf("YES\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36424540/article/details/82717890