zoukankan      html  css  js  c++  java
  • codeforces 1100F Ivan and Burgers 线性基 离线

    题目传送门

    题意:

      给出 n 个数,q次区间查询,每次查询,让你选择任意个下标为 [ l , r ] 区间内的任意数,使这些数异或起来最大,输出最大值。

    思路:离线加线性基。

    线性基学习博客1

    线性基学习博客2

    对于此题,先把区间按照 r 从小到大排序,然后依次处理这些区间,每次插入线性基时,优先保留下标比较大的线性基。查询时,只异或上下标大于 l 的值。

    记住异或的符号的优先级很低,所以  if( res^p[i] > res )这样的代码是会wa死的,要注意(这道题这么写,样例都过不了)

    #include<bits/stdc++.h>
    #define clr(a,b) memset(a,b,sizeof(a))
    using namespace std;
    typedef long long ll; 
    const int maxn=5e5+10;
    int a[maxn],q,n,p[30],pos[30],ans[maxn];
    struct node{
        int l,r,id;
        friend bool operator<(const node &a,const node &b)
        {
            return a.r<b.r;
        }
    }op[maxn]; 
    void init(){
        clr(p,0);
    }
    void add(int val,int id){
        for(int i=20;i>=0;i--)
        {
            if(val&(1<<i))
            {
                if(!p[i]){
                    p[i]=val,pos[i]=id;
                    break;
                }
                if(pos[i]<id){
                    swap(pos[i],id),swap(val,p[i]);
                }
                val^=p[i];
            }
        }
    }
    int query(int l)
    {
        int res=0;
        for(int i=20;i>=0;i--)
        {
            if(pos[i]>=l)
            {
                if((res^p[i])>res)
                {
                    res=res^p[i];
                }
            }
        }
        return res;
    }
    int main(){
        while(cin>>n)
        {
            init();
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
            }
            cin>>q;
            for(int i=1;i<=q;i++)
            {
                scanf("%d%d",&op[i].l,&op[i].r);
                op[i].id=i;
            }
            sort(op+1,op+1+q);
            int l=1;
            for(int i=1;i<=q;i++)
            {
                while(l<=op[i].r&&l<=n)
                {
                    add(a[l],l);
                    l++;
                }
                ans[op[i].id]=query(op[i].l);
            }
            for(int i=1;i<=q;i++)
            {
                printf("%d
    ",ans[i]);
            }
        }
    }
    View Code
  • 相关阅读:
    移动端 推送的那些东西
    git 常用命令
    顶部提示 先下移出来 再上移出去
    ViewPager 高度自适应
    进制转换
    Android 适配
    适配三星Galaxy S8及S8+ 屏幕比例为 18.5:9
    dpi dp px 换算关系
    资源前缀及代码分析总结
    判断是否快速点击或者滑动
  • 原文地址:https://www.cnblogs.com/mountaink/p/10348254.html
Copyright © 2011-2022 走看看