Operation prefix linear yl ----

operation

The meaning of problems: the given length n and m number of columns operating times, each time at the end of a number or the number of columns is added to the sub-query interval R L set the maximum and XOR, by force. \ (n, m \ leq 5 \ times 10 ^ {5} \)

Solution: for all \ (i \ epsilon (1, n) \) maintains a \ ((1, i) \ ) linear group \ (A [I] [32] \) , and the idea is similar to a prefix, and for each linear yl every record what it was last inserted location \ (POS [I] [32] \) (linear group insert function thus necessary to slightly change it), so that the query \ ((L, R ) \) time interval only \ (a [R] \) of greater than or equal pos \ (L \) bit will \ ((L, R) \ ) interval contribute.

PS If there is no mandatory online then press the right endpoint of the interval only needs to maintain a linear ordering based on it.

PSS melon God taught me a prefix linear base orz

Code:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 5;
int n, m;
struct node{
    int p[32], pos[32];
}a[maxn];
void ins(int x) {
    n++;
    a[n] = a[n - 1];
    int pos = n;
    for(int i = 31; i >= 0; i--) {
        if(x & (1 << i)) {
            if(!a[n].p[i]) {
              a[n].p[i] = x;
              a[n].pos[i] = pos;
              return;
            }
            if(a[n].pos[i] < pos) {
              swap(a[n].pos[i], pos);
              swap(a[n].p[i], x);
            }
            x ^= a[n].p[i];
        }   
    }
}
int qmax(int l, int r) {
    int res = 0;
    for(int i = 31; i >= 0; i--) {
        if(a[r].pos[i] < l) continue;
        if((a[r].p[i] ^ res)> res) res ^= a[r].p[i];
    }
    return res;
}
int main() {
    int T;
    cin >> T;
    memset(a[0].p, 0, sizeof(a[0].p));
    memset(a[0].pos, 0, sizeof(a[0].pos));
    while(T--) {
        scanf("%d%d", &n, &m);
        int tmp = n;
        n = 0;
        for(int i = 1; i <= tmp; i++) {
            int x;
            scanf("%d", &x);
            ins(x);
        }
        int las = 0;
        while(m--) {
            int f;
            scanf("%d", &f);
            if(f) {
                int x;
                scanf("%d", &x);
                x ^= las;
                ins(x);
            }
            else{
                int l, r;
                scanf("%d%d", &l, &r);
                l = (l ^ las) % n + 1;
                r = (r ^ las) % n + 1;
                if(l > r) swap(l, r);
                //cout << l << " " << r << '\n';
                las = qmax(l, r);
                printf("%d\n", las);
            }
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/vege-chicken-rainstar/p/11260127.html
Recommended