线性基 xor序列

链接: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范围内



性质:若$x \oplus z=y$, 则$x \oplus y=z$
考虑答案一定是$x \oplus {$一坨东西$}=y$
那么$x \oplus y = {$一坨东西$}$
因此问题变为询问序列中是否有$x \oplus y$
->线性基经典操作
时间复杂度:$O(nlogn)$

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 32, B = 31;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int N;
int P[MAXN];
void Insert(int x) {
    for(int i = B; i >= 0; i--) {
        if((x >> i) & 1) {
            if(!P[i]) {P[i] = x; break;}
            x ^= P[i];
        }
    }
}
int Query(int x) {
    for(int i = B; i >= 0; i--) {
        if((x >> i) & 1) {
            if(!P[i]) return 0;
            x ^= P[i];
        }
    }
    if(x == 0) return 1;
    else return 0;
}
int main() { 
    N = read();
    for(int i = 1; i <= N; i++) {
        int val = read(); Insert(val);
    }
    int Q = read();
    while(Q--) {
        int x = read(), y = read();
        if(Query(x ^ y)) puts("YES");
        else puts("NO");
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值