版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a1046765624/article/details/82533008
链接: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范围内
思路:
明显可以把题意转化一下,k=x^y。
然后就是求n个数中,选择任意个数,是否能异或成k。
然后就是线性基的基本题型。
代码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e5+100;
const int INF=0x3f3f3f3f;
ll a[50];
void insert(long long val)
{
for (int i=32;i>=0;i--)
if (val&(1LL<<i))
{
if (!a[i])
{
a[i]=val;
break;
}
val^=a[i];
}
}
bool qurey(ll x)
{
for (int i=32; i>=0; i--)
if (x&(1LL<<i))
{
if(a[i])x^=a[i];
}
return x==0;
}
int main()
{
int n;
scanf("%d",&n);
int u;
for(int i=1; i<=n; i++)
{
scanf("%d",&u);
insert(u);
}
int q;
scanf("%d",&q);
while(q--)
{
int x,y;
scanf("%d%d",&x,&y);
if(qurey(x^y))
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
return 0;
}