2019 cattle off more school fourth segment tree && B xor-- linear base pay

The meaning of problems

Give you $ n $ sets, each set contains some integer. We say that a collection represents an integer if and only if there exists a subset of its exclusive or equal to the integer. Now you need to answer once asked $ m $ ($ l, r, x $), if $ l $ to $ r $ of each set can represent $ x $.

analysis

To obtain a linear group of each set, and to maintain a linear group with a cross-segment tree, see Code

#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 & lt);
             // B [O] .merge (B [2 * O]); B [O] .merge (B [2 * + O. 1]); 
            B [O] = intersection (B [ 2 * O], B [ 2 * + O . 1 ]); 
        } 
    } 

    // check whether [ql, qr] can be shown in the X 
    BOOL Query ( int O, int L, int R & lt, int QL, int QR, LL X) 
    { 
        int M = L + (R & lt - 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\n");
        else  printf("NO\n");
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/lfri/p/11280505.html