zoukankan      html  css  js  c++  java
  • 线性基模板

    线性基构造方法

    对于每一个数,我们找出他的最高位的 1 在第 i 位, 如果此时 Pi 为零,就将这个数加入线性基,否则异或 Pi 继续找。然后我们就可以在 0 到 k 位上处理好每一位的线性基。这样得到的线性基保证每一位都能有对应的最大值。

    void get_p(LL x)
    {
        for(int i=62;i>=0;i--)
        {
            if((x>>(LL)i))
            {
                if(!p[i])
                {
                    p[i]=x;
                    break;
                }
                x^=p[i];
            }
        }
    }
    

    求最大异或和

    在我们得到的线性基中,从高位到低位用贪心贪掉每一个元素,如果异或了这个元素变大就异或他。

        LL ans=0;
        for(int i=62;i>=0;i--)
            if((ans^p[i])>ans)ans^=p[i];
    

    查询某个数

    我们也是从低到高扫这个数的每一位,如果这第 i 位为 1,就异或上 Pi,然后知道处理到最后一位。如果变成 0 了,那么就是可以的。

    bool check(int x)//查询能否异或成某个数
    {
        for(int i=31;i>=0;i--)
        {
            if(x>>i)x^=p[i];
        }
        return x==0;
    }
    

    线性基求交

    有一道模板题,不过要用到线段树来优化查询
    题目链接:https://ac.nowcoder.com/acm/contest/884/B

    #include<bits/stdc++.h>
    using namespace std;
    const int maxx=5e4+10;
    int a[maxx<<2][32];
    void insert(int x,int temp)//构造线性基
    {
        for(int i=31;i>=0;i--)
        {
            if(x>>i)
            {
                if(!a[temp][i])
                {
                    a[temp][i]=x;
                    break;
                }
                x^=a[temp][i];
            }
        }
    }
    bool check(int x,int temp)//查询能否异或成某个数
    {
        for(int i=31;i>=0;i--)
        {
            if(x>>i)x^=a[temp][i];
        }
        return x==0;
    }
    void pushup(int temp)//线性基求交
    {
        int t1[32],t2[32],l=temp*2,r=temp*2+1;
        for(int i=0;i<32;i++)
            t1[i]=t2[i]=a[l][i];
        for(int i=0;i<32;i++)
        {
            if(a[r][i])
            {
                int x=a[r][i],t=0;
                for(int j=31;j>=0;j--)
                {
                    if(x>>j)
                    {
                        if(!t1[j])
                        {
                            t1[j]=x,t2[j]=t;
                            break;
                        }
                        x^=t1[j],t^=t2[j];
                    }
                }
                if(!x)insert(t,temp);
            }
        }
    }
    void build(int l,int r,int temp)
    {
        if(l==r)
        {
            int s,t;
            scanf("%d",&s);
            while(s--)
            {
                scanf("%d",&t);
                insert(t,temp);
            }
            return;
        }
        int mid=(l+r)/2;
        build(l,mid,temp*2);
        build(mid+1,r,temp*2+1);
        pushup(temp);
    }
    bool query(int l,int r,int p,int q,int x,int temp)
    {
        if(p<=l&&r<=q)
        {
            return check(x,temp);
        }
        int mid=(l+r)/2;
        bool res=1;
        if(p<=mid)res&=query(l,mid,p,q,x,temp*2);
        if(q>mid)res&=query(mid+1,r,p,q,x,temp*2+1);
        return res;
    }
    int main()
    {
        int n,m;
        cin>>n>>m;
        build(1,n,1);
        int p,q,x;
        while(m--)
        {
            scanf("%d%d%d",&p,&q,&x);
            if(query(1,n,p,q,x,1))printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    linq语法2 GLenn
    sql 拼接字符串 GLenn
    每日算法 20130225 GLenn
    linq语法1 GLenn
    每日算法 20130227 GLenn
    每日算法 20130226 GLenn
    jquery ajax 分页 GLenn
    PhoneGap应用开发对策:如何通过苹果审核?
    Xcode 4.1/4.2/4.3/4.4/4.5 + iOS 5.1.1免证书(iDP)开发+真机调试+生成IPA全攻略
    rails 散乱记录
  • 原文地址:https://www.cnblogs.com/HooYing/p/11349578.html
Copyright © 2011-2022 走看看