2019年牛客多校第4场Bxor

链接:https://ac.nowcoder.com/acm/contest/884/B
来源:牛客网

题目描述

Your are given 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 and you should answer if for every i∈[l,r]i in [l,r]i[l,r] ,the i-th set can express x.

线段树+线性基求交。

题意:

给出n个集合。每个集合有一些数,第一个数k为该集合大小,然后是k个数。

m次询问,每次给出l.r.x问是否在l~r区间内,每一个区间是否都可以由任意个数异或出x。

思路:

用线段树维护一个区间线性基的交,对于每一次询问看维护的线性基的交是否可以异或出x就可以了。

有关线性基求交的博客:https://blog.csdn.net/demon_rieman/article/details/88830846

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll maxbit=31;

const ll maxn=5e4+5;
struct node
{
    ll l,r;
    ll basis[maxbit+3];
    void clean()
    {
        l=0,r=0;
        for(ll i=0;i<=maxbit;i++)
            basis[i]=0;
        return ;
    }
    void in(ll k)
    {
        for(ll i=maxbit;i>=0;--i)
        {
            if((k>>i)&1)
            {
                if(basis[i])
                {
                    k^=basis[i];
                }  else {
                    basis[i]=k;
                    break;
                }
            }
        }
        return ;
    }
}tree[maxn<<3];
node Union(node A,node B)
{
    node All,C,D;
    All.clean();
    C.clean();
    D.clean();
    for(ll i=maxbit; i>=0; --i)
    {
        All.basis[i]=A.basis[i];
        D.basis[i] = 1ll << i;
    }
    for(ll i=maxbit; i>=0; --i)
    {
        if(B.basis[i])
        {
            ll v=B.basis[i],k=0;
            bool can = true;

            for(ll j=maxbit; j>=0; --j)
            {
                if((v>>j)&1)
                {
                    if(All.basis[j])
                    {
                        v^=All.basis[j];
                        k^=D.basis[j];
                    }
                    else
                    {
                        can=false;
                        All.basis[j] = v;
                        D.basis[j] = k;
                        break;
                    }
                }
            }

            if(can)
            {
                ll  v=0;
                for(ll j=maxbit; j>=0; --j)
                {
                    if((k>>j)&1)v^=A.basis[j];
                }
                 C.in(v);
            }
        }
    }
    return C;
}
void  build(ll l,ll r,ll rt)
{

    if(l==r)
    {
        ll k;
        scanf("%lld",&k);
        ll val;
        tree[rt].clean();
        tree[rt].l=l;tree[rt].r=r;
        for(ll i=1;i<=k;i++) {scanf("%lld",&val);tree[rt].in(val);}
        return  ;
    }
    // cout<<l<<"_____"<<r<<"_______"<<rt<<endl;
    ll mid=(l+r)>>1;
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    tree[rt].clean();
    tree[rt]=Union(tree[rt<<1],tree[rt<<1|1]);
    tree[rt].l=l;tree[rt].r=r;
    return   ;
}
bool seek_wa(ll x,ll rt)
{
    for(ll i=maxbit;i>=0;--i)
    {
        if((x>>i)&1)
        {
            if(tree[rt].basis[i]) x^=tree[rt].basis[i];
            else return false ;
        }
    }
    if(x==0) return true;
    return false;
}
bool seek_ans( ll sl,ll sr,ll x,ll rt)
{
    ll l=tree[rt].l,r=tree[rt].r;
    if(sl<=tree[rt].l&&tree[rt].r<=sr)
    {
        if(seek_wa(x,rt)) return true;
          return false;
    }

    //cout<<l<<"   "<<r<<"     "<<rt<<endl;
    ll mid = (l+r)>>1;
    if(sr<=mid)
    {
        if(seek_ans(sl,sr,x,rt<<1)) return true;
        return false;
    }
    else if(mid<sl)
    {
        if( seek_ans(sl,sr,x,rt<<1|1)) return true;
        return false;
    }
    else
    {
        if(seek_ans(sl,mid,x,rt<<1)&&seek_ans( mid+1,sr,x,rt<<1|1))return true;
         return false;
    }
    return true;
}
int  main()
{
    ll n,m;
    cin>>n>>m;
    build(1,n,1);
    ll l,r,x;
    for(ll i=0;i<m;i++)
    {
        scanf("%lld%lld%lld",&l,&r,&x);
        bool f=seek_ans(l,r,x,1);
        if(f) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/yzxqq/p/11291410.html