题目描述
小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范围内
很明显的线性基了,利用线性基的性质,我们可以知道看一个数字是否可以被原序列异或得到,那么就是看这个数字能否被线性基异或得到(异或转换一下,两边同时异或x,所以check x^y ),我们check一下即可。
AC代码:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
int n,q,a[N],d[50];
inline void get_lb(int x){
for(int i=31;i>=0;i--){
if(!(x>>i)) continue;
if(!d[i]){
d[i]=x; break;
}else x^=d[i];
}
}
inline int check(int x){
for(int i=31;i>=0;i--){
if(!(x>>i)) continue;
x^=d[i];
}
return x==0;
}
signed main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i],get_lb(a[i]);
cin>>q;
while(q--){
int x,y; cin>>x>>y;
if(check(y^x)) puts("YES");
else puts("NO");
}
return 0;
}