Operation HDU

Operation (HDU - 6579)

番外:

初学线性基,推荐一篇线性基学习笔记

线性基就是一个两两元素异或没有冗余的元素集合。

我们在集合内每一位记录一个贡献当前位的数字,就可以查询区间异或极值。

题意:

给一个初始序列,要求支持两种操作:

  • 查询一个区间内的元素异或最大值。
  • 向序列尾部添加一个元素。

题解:

我们考虑做一个前缀线性基和,然后插入元素的同时记录坐标,来保证让贡献高位的元素尽量靠右。这样可以保证在每个线性基和里查询区间的时候,查询到的数尽量大(贡献的位置尽量高)。查询的时候只查询坐标大于等于L的就可以了。

#include <bits/stdc++.h>
#define fopi freopen("in.txt", "r", stdin)
#define fopo freopen("out.txt", "w", stdout)
using namespace std;
typedef long long LL;
const int maxn = 1e6 + 5;
typedef pair<int, int> Pair;

struct LinearBasis{
    #define N 30
    Pair a[N+1];

    void init() {
        memset(a, 0, sizeof(a));
    }

    bool insert(int val, int pos) {
        for (int i = N; i >= 0; i--) if (val & (1ll << i)) {
            if (a[i].first == 0) {
                a[i].first = val;
                a[i].second = pos;
                break;
            }
            else if (a[i].second < pos) {
                swap(val, a[i].first);
                swap(pos, a[i].second);
            }
            val ^= a[i].first;
        }
        return val > 0;
    }

    int query_Max(int l) {
        int res = 0;
        for (int i = N; i >= 0; i--)
            if ((res^a[i].first) > res && a[i].second >= l)
                res ^= a[i].first;
        return res;
    }
}LB[maxn];

int T, n, m;
LL x;

int main() {

    //fopi;

    scanf("%d", &T);
    for (int ca = 1; ca <= T; ca++) {
        LB[0].init();

        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++) {
            scanf("%lld", &x);
            LB[i] = LB[i-1];
            LB[i].insert(x, i);
        }

        int ans = 0;
        for (int i = 1; i <= m; i++) {
            int op, x, y;
            scanf("%d%d", &op, &x);
            if (op == 0) {
                scanf("%d", &y);
                x = (x^ans) % n + 1, y = (y^ans) % n + 1;
                if (x > y) swap(x, y);
                printf("%d
", ans = LB[y].query_Max(x));
            }
            else {
                ++n;
                LB[n] = LB[n-1];
                LB[n].insert(x^ans, n);
            }
        }
    }
}

原文地址:https://www.cnblogs.com/ruthank/p/11354434.html