zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    获得oc支持的国家和语言
    在iOS开发中,经常需要调用其它App,如拨打电话、发送邮件等。UIApplication:openURL:方法是实现这一目的的 ##转
    UITableView的分组 快速索引
    xcode调试技巧
    组件data中必须是function的原因
    组件中的 data 和methods
    使用 components 定义私有组件
    使用 transition-group 元素实现列表动画
    组件化和模块化
    使用钩子函数模拟小球半场动画
  • 原文地址:https://www.cnblogs.com/tian-luo/p/11256809.html
Copyright © 2011-2022 走看看