• Codeforces Round #532 (Div. 2):F. Ivan and Burgers(贪心+异或基)


    F. Ivan and Burgers

    题目链接:https://codeforces.com/contest/1100/problem/F

    题意:

    给出n个数,然后有多个询问,每次回答询问所给出的区间的异或和最大值。

    题解:

    考虑离线做法,先把所有的询问区间按照右端点进行排序,然后从1开始逐个将ai插入,插入线性基的同时记录一下位置,最后扫一下,看看哪些的位置是不小于li的即可加入答案。

    这种做法在时间复杂度上面是可行的,但是需要注意的是,如果在i这个位置插入最高位为x的线性基,同时在j这个位置又有一个最高位为x的线性基,那么对于最高位为x的线性基,我们是肯定保留后面的位置是更优的。在替换位置过后,注意一下插入的线性基也发生了变化。

    代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 5e5+5;
    int n,q;
    int c[N],ans[N],pos[N];
    int a[25];
    struct P{
        int l,r,id;
        bool operator < (const P &A)const{
            return r<A.r;
        }
    }p[N];
    void insert(int val,int id){
        for(int i=20;i>=0;i--){
            if(!((1<<i)&val)) continue ;
            if(!a[i]){
                a[i]=val;
                pos[i]=id;
                break ;
            }
            if(pos[i]<id) swap(pos[i],id),swap(a[i],val);
            val^=a[i];
        }
    }
    int query(int l){
        int res=0;
        for(int i=20;i>=0;i--){
            if(((res^a[i])>res) && pos[i]>=l) res^=a[i];
        }
        return res;
    }
    int main(){
        ios::sync_with_stdio(false);cin.tie(0);
        cin>>n;
        for(int i=1;i<=n;i++) cin>>c[i];
        cin>>q;
        for(int i=1;i<=q;i++) cin>>p[i].l>>p[i].r,p[i].id=i;
        sort(p+1,p+q+1);
        int r=1;
        for(int i=1;i<=q;i++){
            while(r<=p[i].r) insert(c[r],r),r++;
            ans[p[i].id]=query(p[i].l);
        }
        for(int i=1;i<=q;i++) cout<<ans[i]<<'
    ';
        return 0;
    }
  • 相关阅读:
    3
    正确的消费理念和方式
    2
    1
    善待精力,保持体力,保持热情
    为什么不从今天开始呢?
    c++中的新成员
    函数重载分析下
    函数重载分析上
    函数参数的扩展
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/10422188.html
Copyright © 2020-2023  润新知