2017icpc Xi'an A.XOR

2017icpc Xi'an A.XOR

Meaning of the questions:

Length \ (n-\) array, \ (Q \) times query, query given every \ (L, R & lt \) , from \ ([l, r] \ ) is selected such that the number of digital numbers interval XOR and or \ (k \) maximum.

Ideas:

Random process group is a linear XOR problem, the maximum for this interval may be considered exclusive or combined with maintenance of the linear segment tree group.

Consider how we can have \ (k | (a_ {i_1 } \ xor \ a_ {i_2} \ xor \, ..., \ xor \ a_ {i_m}) \) maximum.

The idea is that the beginning: to come up with a linear range of the base, and then bit by bit from a high level of search, if \ (k \) have \ (1 \) , it does not consider this a linear group, if there is no \ (1 \) , we will certainly consider, but soon to include a counter-example.

Consider \ (k \) what it takes?

When \ (k \) This one has \ (1 \) , we can try to take care of him if this one does not \ (1 \) , we try to choose from to fill in the numbers, even if it is not.

So the \ (K \) negated, for each segment tree node into \ (K \ & A (I) \) , each query asking \ ([l, r] \ ) maximum result, the final result or the most \ (k \) .

Correctness:

When the pair \ (k \) after negated, for \ (a (i) \) with the operation, in fact, looking for \ (a (i) \) This bit has no \ (1 \) .

It is also likely to have been \ (a (i) \) have \ (1 \) place to take the anti \ (k \) get rid of, this need not worry, because the final answers or \ (k \) , on the back.

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e4+10;

int n, m, k, a[maxn];
int l, r, ans;

struct LineBase
{
    int p[32];
    void init() {memset(p, 0, sizeof p);}
    void ins(int x)
    {
        for(int i = 30; i >= 0; i--)
        {
            if(x&(1<<i))
            {
                if(!p[i])
                {
                    p[i] = x;
                    return;
                }
                x ^= p[i];
            }
        }
    }

    int qmax()
    {
        int res = 0;
        for(int i = 30; i >= 0; i--)
            res = max(res, res^p[i]);
        return res;
    }
};

struct SegmentTree
{
    int l, r;
    LineBase t;
    #define lson (p<<1)
    #define rson (p<<1|1)
    #define l(x) tree[x].l
    #define r(x) tree[x].r
    #define t(x) tree[x].t
}tree[maxn<<2];

LineBase merge_base(LineBase a, LineBase b)
{
    for(int i = 30; i >= 0; i--)
        if(a.p[i]) b.ins(a.p[i]);
    return b;
}

void build(int p, int l, int r)
{
    l(p) = l, r(p) = r;
    t(p).init();
    if(l == r)
    {
        t(p).ins(a[l]);
        return;
    }
    int mid = (l+r)>>1;
    build(lson, l, mid);
    build(rson, mid+1, r);
    t(p) = merge_base(t(lson), t(rson));
}

LineBase ask(int p, int l, int r)
{
    if(l <= l(p) && r(p) <= r) return t(p);
    int mid = (l(p)+r(p))>>1;
    if(mid >= r) return ask(lson, l, r);
    else if(mid < l) return ask(rson, l, r);
    else return merge_base(ask(lson, l, r), ask(rson, l, r));
}

void solve()
{
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        a[i] = a[i]&(~k);
    }
    build(1, 1, n);
    while(m--)
    {
        scanf("%d%d", &l, &r);
        LineBase tmp = ask(1, l, r);
        ans = tmp.qmax();
        ans = ans|k;
        printf("%d\n", ans);
    }
}

int main()
{
    int T; scanf("%d", &T);
    while(T--) solve();
    return 0;
}

Guess you like

Origin www.cnblogs.com/zxytxdy/p/12543871.html