zoukankan      html  css  js  c++  java
  • 2019牛客多校第四场B xor——线段树&&线性基的交

    题意

    给你 $n$ 个集合,每个集合中包含一些整数。我们说一个集合表示一个整数当且仅当存在一个子集其异或和等于这个整数。现在你需要回答 $m$ 次询问 ($l, r, x$),是否 $l$ 到 $r$ 的每个集合都能表示 $x$.

    分析

    先求出每个集合的线性基,然后用线段树维护线性基的交,详见代码

    #include<bits/stdc++.h>
    #define reg register
    using namespace std;
    typedef long long ll;
    
    const int bits = 31;
    const int maxn = 100000 + 10;
    int n, q;
    ll a[maxn][32];
    
    struct LBase {
        //const static int bits = 31;   //0~31位
        ll d[bits+1], tmp[bits+1];   //线性基
        bool flag = false;  //记录是否cnt < n
        LBase() {memset(d, 0, sizeof d);}
        void insert(ll x)
        {
            for(int i=bits;~i;i--)
                if(x&(1ll<<i))
                {
                    if(!d[i]){ d[i]=x; break;}
                    else  x ^= d[i];
                }
           flag = true;
        }
        bool check(ll x)  //返回true表示已经能被表示
        {
            for(int i=bits;~i;i--)
                if(x&(1ll<<i))
                {
                    if(!d[i]) return false;
                    else x ^= d[i];
                }
            return true;
        }
        ll qmax(ll res=0)
        {
            for(int i=bits;~i;i--)
                res=max(res,res^d[i]);
            return res;
        }
        ll qmin()
        {
            if(flag) return 0;
            for(int i=0;i<=bits;i++)
                if(d[i]) return d[i];
        }
        ll query(ll k)  //查询第k小
        {
            ll res=0; int cnt=0;
            k-=flag; if(!k)return 0;
            for(int i=0;i<=bits;i++){
                for(int j=i-1;~j;j--)
                    if(d[i]&(1ll<<j)) d[i]^=d[j];
                if(d[i]) tmp[cnt++]=d[i];
            }
            if(k>=(1ll<<cnt))return -1;
            for(int i=0;i<cnt;i++)
                if(k&(1ll<<i)) res^=tmp[i];
            return res;
        }
        void merge(const LBase &a) {   //求并集
            for (int i = bits; i >= 0; --i)
                if (a.d[i]) insert(a.d[i]);
        }
    };
    
    LBase intersection(const LBase &a,const LBase &b)  //求交集
    {
        LBase ans, c=b,d=b;
        for(int i = 0;i <= bits;i++)
        {
            ll x =a.d[i];
            if(!x) continue;
            int j=i;ll T=0;
            for(;j>=0;--j)
            if((x>>j)&1)
            if(c.d[j]){x^=c.d[j];T^=d.d[j];}
            else break;
            if(!x)ans.d[i]=T;
            else {c.d[j]=x;d.d[j]=T;}
        }
        return ans;
    }
    
    struct SegTree
    {
        LBase b[maxn << 2];
        void build(int o, int L, int R)
        {
            int M = L + (R-L) / 2;
            if(L == R)
            {
                for(int i = 0;i < 32;i++) b[o].insert(a[L][i]);
            }
            else
            {
                build(2*o, L, M);
                build(2*o+1, M+1, R);
                //b[o].merge(b[2*o]); b[o].merge(b[2*o+1]);
                b[o] = intersection(b[2*o], b[2*o+1]);
            }
        }
    
        //查询[ql, qr]中是否都能表示出x
        bool query(int o,int L,int R, int ql, int qr, ll x)
        {
            int M = L + (R - L) / 2;
            bool flag1 = true, flag2 = true;
            if(ql <= L && R <= qr)  return b[o].check(x);
            if(ql <= M)  flag1 = query(2*o, L, M, ql, qr, x);
            if(qr > M)  flag2 = query(2*o+1, M+1, R, ql, qr, x);
            return flag1 && flag2;
        }
    
    }seg;
    
    int main(){
        scanf("%d%d", &n, &q);
        for(int i = 1;i <= n;i++)
        {
            int sz; scanf("%d", &sz);
            for(int j = 0;j < sz;j++)  scanf("%lld", &a[i][j]);
            for(int j=sz; j < 32;j++)  a[i][j] = 0;
        }
        seg.build(1, 1, n);
        while(q--)
        {
            int l, r; ll x;
            scanf("%d%d%lld", &l, &r, &x);
            if(seg.query(1, 1, n, l, r, x)) printf("YES
    ");
            else  printf("NO
    ");
        }
        return 0;
    }
  • 相关阅读:
    【认证】Apache Shiro对象概念
    【Java基础】char
    【Http】keepalive
    【Nginx】Nginx处理请求过程
    【CSS】块级元素和行内元素
    未A,或用水法,或不熟的题
    2017初二上期中考试总结
    动态规划中的单调队列优化_补充
    NOIP2017普及组翻车记
    对拍模板
  • 原文地址:https://www.cnblogs.com/lfri/p/11280505.html
Copyright © 2011-2022 走看看