zoukankan      html  css  js  c++  java
  • 线性基—转载的博客

    转载处:https://www.cnblogs.com/letlifestop/p/10269298.html

    题意:给定一个数字n,接下来给出n个数字。再给出数字m,接下来给出m组询问 l , r .对于每个询问回答 区间 l,r数的最大异或值。  

    数据范围  1<= n,m<=1e5    ci<=1e6;

    具体思路:贪心,我们按照右边界的大小进行排序,小的在上面,大的往下安排,然后每一次我们寻找1--> r区间内的线性基,如果当前的线性基能往后移动,我们就选取后面的这个线性基(因为我们对输入的数据进行了排序,后面的r肯定是大的,所以我们将选取的线性基尽量的往后安排肯定是没有问题的,然后我们查询的时候,看一下当前位上有线性基的时候,先判断这个线性基取的时候是从哪个数里面取出来的,然后再看一下这个数是不是大于l的,如果是的话,这个线性基就是可用的,我们通过这些线性基寻找一个最大值就可以了)

    #include<bits/stdc++.h>
    using namespace std;
    # define ll long long
    const int maxn =5e5+100;
    int sto[maxn],p[maxn],ans[maxn],ord[maxn];
    struct node
    {
        int l,r,id;
    } q[maxn];
    bool cmp(node t1,node t2)
    {
        return t1.r<t2.r;
    }
    void add(int num,int id)
    {
        for(int i=20; i>=0; i--)
        {
            if(((1<<i)&num)==0)
                continue;
            if(p[i]==0)
            {
                p[i]=num;
                ord[i]=id;
                break;
            }
            if(ord[i]<id)//交换的时候都需要交换。
            {
                swap(ord[i],id);
                swap(num,p[i]);
            }
            num^=p[i];
        }
    }
    int query(int t)
    {
        int sum=0;
        for(int i=20; i>=0; i--)
        {
            if(ord[i]>=t&&(sum^p[i])>sum)
                sum^=p[i];
        }
        return sum;
    }
    int main()
    {
        int n,m;
        scanf("%d",&n);
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&sto[i]);
        }
        scanf("%d",&m);
        for(int i=1; i<=m; i++)
        {
            scanf("%d %d",&q[i].l,&q[i].r);
            q[i].id=i;
        }
        sort(q+1,q+m+1,cmp);
        int num=0;
        for(int i=1; i<=m; i++)
        {
            while(num<q[i].r)
                add(sto[++num],num);//将1-r都给压进去。
            ans[q[i].id]=query(q[i].l);
        }
        for(int i=1; i<=m; i++)
        {
            printf("%d
    ",ans[i]);
        }
        return 0;
    }
  • 相关阅读:
    Redis和MySQL的结合方案
    Java-CyclicBarrier的简单样例
    第十话-模板方法模式
    Codeforces 19D Points 线段树+set
    操作系统: 二级文件夹文件系统的实现(c/c++语言)
    mongodb数据库的启动和停止
    XML,HTML,XHTML
    android之ViewStub的使用
    教你实现语音识别(基于科大讯飞)
    android通过代码判断手机是否root
  • 原文地址:https://www.cnblogs.com/rainyskywx/p/11384500.html
Copyright © 2011-2022 走看看