HDU6579 2019 HDU Multi-School Training Competition 1st 1002 (Linear Base)

Posted by kubak on Tue, 30 Jul 2019 19:40:03 +0200

Port: http://acm.hdu.edu.cn/showproblem.php?pid=6579

Topic:

Two operations

1. Add a number at the end of the sequence

2. Query Interval XOR Maximum

Force Online

Questions:

Violence can be used to maintain an interval linear basis with a data structure, but it can't be overridden.

Greedily maintains the prefix linear base (upper triangle form) of the sequence, and for each linear base, a number appears to the right of the position

Keep words as high as possible, that is, when inserting a new number, record the digits that appear in the corresponding position at the same time.

And if a new number is more to the right than the original number in the position, it will be inserted

Push the original number down.

When maximizing, traverse from high to low if the number on that bit appears at the left end of the query interval

On the right and making the answer larger, it's XOR in the answer.

For each bit of a linear base, the number at a higher position than the linear base it has exclusively passed must appear to its right (no)

Then it will be inserted in that location, so the correctness of the procedure is obvious.

Code:

#include <set>
#include <map>
#include <cmath>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
const int maxn = 1e6 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
LL quick_pow(LL x, LL y) {
    LL ans = 1;
    while(y) {
        if(y & 1) {
            ans = ans * x % mod;
        } x = x * x % mod;
        y >>= 1;
    } return ans;
}
int f[maxn][32];
int pos[maxn][32];
void add(int x, int i) {
    int k = i;
    int tmp;
    for (int j = 30; j >= 0; --j) f[i][j] = f[i - 1][j], pos[i][j] = pos[i - 1][j];
    for (int j = 30; j >= 0; --j) if (x >> j) {
            if (!f[i][j]) {
                f[i][j] = x;
                pos[i][j] = k;
                break;
            } else {
                if (k > pos[i][j]) {
                    tmp = k, k = pos[i][j], pos[i][j] = tmp;
                    tmp = x, x = f[i][j], f[i][j] = tmp;
                }
                x ^= f[i][j];
            }
        }

}
int main() {
#ifndef ONLINE_JUDGE
    FIN
#endif
    int T;
    scanf("%d", &T);
    while(T--) {
        memset(pos, 0, sizeof(pos));
        memset(f, 0, sizeof(f));
        int n, m;
        scanf("%d%d", &n, &m);
        for(int i = 1, x; i <= n; i++) {
            scanf("%d", &x);
            add(x, i);
        }
        int lastans = 0;
        while(m--) {
            int op;
            int l, r, x;
            scanf("%d", &op);
            if(op == 0) {
                scanf("%d%d", &l, &r);
                // debug2(l, r);
                l = (l ^ lastans) % n + 1;
                r = (r ^ lastans) % n + 1;
                if(l > r) swap(l, r);
                int ans = 0;
                for(int j = 30; j >= 0; --j) {
                    if((ans ^ f[r][j]) > ans && pos[r][j] >= l) {
                        ans ^= f[r][j];
                    }
                }
                printf("%d\n", ans);
                lastans = ans;
            } else {
                scanf("%d", &x);
                x^=lastans;
                n++;
                add(x, n);
            }
        }
    }
    return 0;
}

Topics: Python PHP iOS