zoukankan      html  css  js  c++  java
  • xor(线性基的合并)

    题目链接:https://ac.nowcoder.com/acm/contest/884/B

    链接:https://ac.nowcoder.com/acm/contest/884/B
    来源:牛客网

    时间限制: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]i in [l,r]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]i in [l,r]i[l,r] ,the i-th set can express x, you need to print “YES”, and "NO" otherwise.
    示例1

    输入

    复制
    1 3
    2 1 2
    1 1 0
    1 1 3
    1 1 4

    输出

    复制
    YES
    YES
    NO

    备注:

    1≤n,m≤500001 le n,m le 500001n,m50000 ,1≤sz≤321 le sz le 321sz32,1≤l≤r≤n1 le l le r le n1lrn ,the every integer in input ∈[0,232)in [0,2^{32})[0,232)。
    思路:问一个集合挑选出一些数是否能异或为一个数,显然是线性基。 但是题目要求l,r区间内所有集合都要查询,所以暴力显然行不通
    那么区间查询显然会想到线段树,维护区间, 这里介绍一下线性基的交,看了代码,自己也不是很懂。 以后真的碰到要用到线性基的交就只能靠板子了。 线段树维护区间的交
    这样就能区间查询是否能异或出某个数了。整体就这样了
    线性基合并过程:

    看代码:
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    typedef long long LL;
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    const int maxn=50000+5;
    struct Basis
    {
        Basis()
        {
            memset(basis,0,sizeof(basis));
        }
        LL basis[35];
    
        void Update(LL x)//求线性基
        {
            for(LL i=32;i>=0;i--)
            {
                if(x&(1ll<<i))
                {
                    if(!basis[i])
                    {
                        basis[i]=x;break;
                    }
                    x^=basis[i];
                }
            }
        }
        bool Ask(LL x)
        {
            for(LL i=32;i>=0;i--)
            {
                if(x&(1ll<<i))
                {
                    if(basis[i]) x^=basis[i];
                    else return false;
                }
            }
            return true;
        }
    }a[maxn],T[maxn<<2];
    void Push_up(LL rt)//线性基的合并
    {
        Basis tmp=T[rt<<1],v1=T[rt<<1],v2=T[rt<<1|1];
        for(LL i=0;i<32;i++)
        {
            if(v2.basis[i])
            {
                bool flag=true;
                LL x=v2.basis[i],now=0;
                for(LL j=31;j>=0;j--)
                {
                    if(x&(1ll<<j))
                    {
                        if(!tmp.basis[j])
                        {
                            flag=false;
                            tmp.basis[j]=x;
                            v1.basis[j]=now;
                            break;
                        }
                        x^=tmp.basis[j];now^=v1.basis[j];
                    }
                }
                if(flag) T[rt].Update(now);
            }
        }
    }
    void Build(LL l,LL r,LL rt)
    {
        if(l==r)
        {
            T[rt]=a[l];return ;
        }
        LL mid=(l+r)>>1;
        Build(l,mid,rt<<1);Build(mid+1,r,rt<<1|1);Push_up(rt);
    }
    
    bool Query(LL l,LL r,LL rt,LL L,LL R,LL x)
    {
        bool flag=true;
        if(L<=l&&r<=R) return T[rt].Ask(x);
        LL mid=(l+r)>>1;
        if(L<=mid) flag&=Query(l,mid,rt<<1,L,R,x);
        if(R>mid) flag&=Query(mid+1,r,rt<<1|1,L,R,x);
        return flag;
    }
    int main()
    {
        LL N,M;
        cin>>N>>M;
        for(LL i=1;i<=N;i++)
        {
            LL len;cin>>len;
            for(LL j=1;j<=len;j++)
            {
                LL x;cin>>x;a[i].Update(x);
            }
        }
        Build(1,N,1);
        while(M--)
        {
            LL l,r,x;cin>>l>>r>>x;
            if(Query(1,N,1,l,r,x)) printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }
     
    当初的梦想实现了吗,事到如今只好放弃吗~
  • 相关阅读:
    安装和配置SQL
    自定义中间件封装为模块
    留言板
    Spring Factories机制
    JVM参数配置
    全链路监控的方案概述与比较
    Lombok注解-@SneakyThrows
    @FeignClient注解 中属性 contextId使用
    @validate或@valid注解进行数据校验的解决方案
    maven的settings.xml标签详解
  • 原文地址:https://www.cnblogs.com/caijiaming/p/11263221.html
Copyright © 2011-2022 走看看