xor序列(线性基)

版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}

猜你喜欢

转载自blog.csdn.net/a1046765624/article/details/82533008