• 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;
    }
    

      

  • 相关阅读:
    内存缓存 原理 实现
    ssh 内在溢出
    android 解析XML方式(三)
    android 解析XML方式(二)
    android 解析XML方式(一)
    (三)、
    (二)、SSL证书
    (一)、http原理
    httpsClient实例
    飞信免费发送接口API的测试 httpClient
  • 原文地址:https://www.cnblogs.com/yzxqq/p/11291410.html
Copyright © 2020-2023  润新知