xor

xor

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld

题目描述

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] ,the i-th set can express x.

输入描述:

The first line contains two integers n,m.

For each of the following n lines, the first integer sz stands for the size of this set and the following sz integers stand for the elements in this set. The sets are described from number 1 to n.

For each of the following m lines, there're three integers l,r,x that means a query.

输出描述:

For each query, output a line.

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

输入

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

输出

YES
YES
NO

备注:

1≤n,m≤500001≤sz≤321≤l≤r≤n ,the every integer in input ∈[0,232)
链接:https://ac.nowcoder.com/acm/contest/884/B
来源:牛客网

线性基,Mark一下线性基的交。
#include<bits/stdc++.h>
using namespace std;

const int Digit=60;

struct L_B
{
    long long basis[Digit+1];
    L_B()
    {
        memset(basis,0,sizeof(basis));
    }

    void operator = (const L_B & s)
    {
        for(int i=0; i<=Digit; i++)basis[i]=s.basis[i];
    }

    bool insert(long long val)
    {
        for (int i=Digit; i>=0; i--)
            if (val&(1LL<<i))
            {
                if (!basis[i])
                {
                    basis[i]=val;
                    break;
                }
                val^=basis[i];
            }
        return val>0;
    }

    bool check(long long val)
    {
        for (int i=Digit; i>=0; i--)
        if (val&(1LL<<i))
        {
            if(basis[i])val^=basis[i];
            else
                return 0;
        }
        return 1;
    }

    long long query_max()
    {
        long long ret=0;
        for (int i=Digit;i>=0;i--)
            if ((ret^basis[i])>ret)
                ret^=basis[i];
        return ret;
    }

};

L_B Merge(L_B A,L_B B)
{
    L_B All, C, D;
    for (int i = Digit; i >= 0; i--)
    {
        All.basis[i] = A.basis[i];
        D.basis[i] = 1ll << i;
    }
    for (int i = Digit; i >= 0; i--)
    {
        if (B.basis[i])
        {
            long long v = B.basis[i], k = 0;
            bool can = true;
            for (int j = Digit; j >= 0; j--)
            {
                if (v & (1ll << j))
                {
                    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)
            {
                long long v = 0;
                for (int j = Digit; j >= 0; j--)
                {
                    if (k & (1ll << j))
                    {
                        v ^= A.basis[j];
                    }
                }
                C.insert(v);
            }
        }
    }
    return C;
}




const int N = 5e4+50;
struct ss
{
    int l,r;
    L_B lb;
};
L_B base[N];
ss tree[4*N];


void build(int v,int l,int r)
{
    int mid=(l+r)/2;
    tree[v].l=l;
    tree[v].r=r;

    if(l==r)
    {
        tree[v].lb=base[l];
        return;
    }

    build(2*v,l,mid);
    build(2*v+1,mid+1,r);

    tree[v].lb=Merge(tree[2*v].lb,tree[2*v+1].lb);
}

bool query(int v,int l,int r,int x)
{
   // printf("%d %d %d
",tree[v].l,tree[v].r,x);
    if(tree[v].l==l&&tree[v].r==r)return tree[v].lb.check(x);

    int mid=(tree[v].l+tree[v].r)/2;
    if(r<=mid)return query(2*v,l,r,x);
    else
        if(l>mid)return query(2*v+1,l,r,x);
    else
    {
        return query(2*v,l,mid,x)&&query(2*v+1,mid+1,r,x);
    }
}

int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        int sz;
        scanf("%d",&sz);
        while(sz--)
        {
            int a;
            scanf("%d",&a);
            base[i].insert(a);
        }
    }

    build(1,1,n);
    while(m--)
    {
        int l,r,x;
        scanf("%d %d %d",&l,&r,&x);
        printf("%s
",query(1,l,r,x) ? "YES" : "NO");
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/tian-luo/p/11256809.html