[2019牛客多校训练第4场]xor

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K

链接:https://ac.nowcoder.com/acm/contest/884/B
来源:牛客网
分数:2500 我觉得是常规的数据结构题(
题目描述
Your are given n n n sets.Every set contains some integers.
We say a set can express an integer, only when there exists a subset of the set such that the bitwise-xor of the elements in the subset is equal to that integer.
Now you need to answer m queries. Each query will give you three integers l , r , x l,r,x l,r,x and you should answer if for every i ∈ [ l , r ] i∈[l,r] i[l,r],the i-th set can express x x x.
输入描述:

The first line contains two integers n , m n,m n,m.
For each of the following n n n lines, the first integer s z sz sz stands for the size of this set and the following s z sz sz integers stand for the elements in this set. The sets are described from number 1 1 1 to n n n.
For each of the following m m m lines, there’re three integers l , r , x l,r,x l,r,x that means a query.

输出描述:

For each query, output a line.
If for every i ∈ [ l , r ] i∈[l,r] i[l,r] ,the i-th set can express x x x, you need to print “YES”, and “NO” otherwise.

示例1
输入
复制

1 3
2 1 2
1 1 0
1 1 3
1 1 4

输出
复制

YES
YES
NO

备注:

1 ≤ n , m ≤ 50000 , 1 ≤ s z ≤ 32 , 1 ≤ l ≤ r ≤ n 1 \le n,m \le 50000 ,1 \le sz \le 32,1 \le l \le r \le n 1n,m500001sz321lrn,the every integer in input ∈ [ 0 , 2 32 ) \in [0,2^{32}) [0,232)

题意:
给定n个集合,每次询问一个区间 l , r l,r l,r和一个数字 x x x,询问从集合 l l l r r r中,是否每个集合都可以满足 x x x是若干个集合元素的异或和。

题解:
对于一个集合来说,我们可以把这个集合用线性基来表示,然后对于一个区间,我们可以求出这个区间的线性基的交集,然后将直接对这个交集询问 x x x即可

#include<bits/stdc++.h>
#define uint unsigned int
#define ll long long
using namespace std;
struct lb{
    ll b[34];
    void CLEAR(){
        memset(b,0,sizeof(b));
    }
    bool ins(ll x){
        for(int i=31;i>=0;i--){
            if(x&(1LL<<i)){
                if(!b[i]){
                    b[i]=x;
                    break;
                }
                x^=b[i];
            }
        }
        return x!=0;
    }
    bool check(ll x){
        for(int i=31;i>=0;i--){
            if(x&(1LL<<i)){
                if(b[i])x^=b[i];
                else return 0;
            }
        }
        return 1;
    }
};
struct seg{
    int l,r;
    lb lin;
}tr[200004];
int n,m;
void update(int k){//线性基求交集
    lb a=tr[k<<1|1].lin,b=tr[k<<1|1].lin;
    for(int i=0;i<32;i++){
        if(!tr[k<<1].lin.b[i])continue;
        ll temp=0,x=tr[k<<1].lin.b[i];
        int j;
        for(j=i;j>=0;j--){
            if(x&(1LL<<j)){
                if(a.b[j]){
                    x^=a.b[j];
                    temp^=b.b[j];
                }
                else break;
            }
        }
        if(x==0)tr[k].lin.b[i]=temp;
        else{
            a.b[j]=x;
            b.b[j]=temp;
        }
    }
}
void build(int k,int l,int r){
    tr[k].l=l;tr[k].r=r;
    tr[k].lin.CLEAR();
    if(l==r){
        int sz;
        ll x;
        scanf("%d",&sz);
        for(int i=1;i<=sz;i++){
            scanf("%lld",&x);
            tr[k].lin.ins(x);
        }
        return ;
    }
    int mid=(l+r)>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    update(k);
}
bool query(int k,int a,int b,ll x){
    int l=tr[k].l,r=tr[k].r;
    if(a==l&&r==b){
        return tr[k].lin.check(x);
    }
    int mid=(l+r)>>1;
    if(b<=mid)return query(k<<1,a,b,x);
    else if(a>mid)return query(k<<1|1,a,b,x);
    else{
        return query(k<<1,a,mid,x)&&query(k<<1|1,mid+1,b,x);
    }
}
int w33ha(){
    build(1,1,n);
    while(m--){
        int l,r;ll x;
        scanf("%d%d%lld",&l,&r,&x);
        bool t=query(1,l,r,x);
        if(t)puts("YES");
        else puts("NO");
    }
    return 0;
}
int main(){
    while(scanf("%d%d",&n,&m)!=EOF)w33ha();
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值