Codeforces 1100F(线性基+贪心)

Posted duskob

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 1100F(线性基+贪心)相关的知识,希望对你有一定的参考价值。

题目链接

题意

给定序列,$q(1leq q leq 100000) $次询问,每次查询给定区间内的最大异或子集。

思路

涉及到最大异或子集肯定从线性基角度入手。将询问按右端点排序后离线处理询问,对线性基的每一位贪心的保留靠后的。

代码

#include <bits/stdc++.h>
#define DBG(x) cerr << #x << " = " << x << endl;

using namespace std;

const int N = 500000 + 5;

int n, m, a[N], ans[N], L = 1;
struct node {
    int l, r, id;
    bool operator < (const node & a) const {
        if(r != a.r) return r < a.r;
        return l < a.l;
    }
}b[N];

struct base {
    int b[21], pos[21];

    void add(int x, int id) {
        for(int i = 20; i >= 0; i--) {
            if((x >> i) & 1) {
                if(!pos[i]) {
                    b[i] = x, pos[i] = id;
                    return;
                }
                if(id > pos[i]) {swap(x, b[i]); swap(id, pos[i]);}
                x ^= b[i];
            }
        }
    }

    int query(int id) {
        int res = 0;
        for(int i = 20; i >= 0; i--) {
            if(pos[i] >= id && (res ^ b[i]) > res) res ^= b[i];
        }
        return res;
    }
}bs;

int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    scanf("%d", &m);
    for(int i = 1; i <= m; i++) scanf("%d%d", &b[i].l, &b[i].r), b[i].id = i;
    sort(b + 1, b + 1 + m);
    for(int i = 1; i <= m; i++) {
        while(L <= b[i].r) bs.add(a[L], L), L++;
        ans[b[i].id] = bs.query(b[i].l);
    }
    for(int i = 1; i <= m; i++) printf("%d
", ans[i]);
    return 0;
}

 

以上是关于Codeforces 1100F(线性基+贪心)的主要内容,如果未能解决你的问题,请参考以下文章

hdu 6579 Operation (在线线性基)

HDOJ6579Operation(线性基)

CodeForces 1100F Ivan and Burgers

F. Ivan and Burgers(线性基,离线)

bzoj2460元素(线性基,贪心)

BZOJ 2460: [BeiJing2011]元素 贪心,线性基