Linear basis + union search

 

Given a 1-base array {a}, there are N operations, each of which invalidates a position. The weight of an interval is defined as the maximum value of the XOR sum of selected numbers in this interval. Find the maximum value of the weights of all intervals that do not contain invalid positions before each operation.

Enter description:

The first line reads a positive integer (1 <= n <= 10 5 )

The second line reads n positive integers, the i-th represents a[i] (0<= a[i] <= 10 9 )

The third line reads n positive integers, the i-th represents the position of x[i], which is the i-th operation, ensuring that x[i] are different from each other.

Output description:

output n lines of answer
Example 1

enter

10
169 816 709 896 58 490 97 254 99 796
4 2 3 10 5 6 1 8 9 7

output

1023
994
994
994
490
490
254
254
99
Question 97 

Meaning: Each time the number of a position is invalidated, what is the maximum XOR value in the continuous interval?
Idea analysis: Every time a position is invalidated, then this problem can be considered in reverse, adding a number each time, which is better than the deletion operation. You can use the union search, and then you can set a linear basis.
Code example:
#define ll long long
const int maxn = 1e5+5;
const int mod = 1e9+7;
const double eps = 1e-9;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;

int n;
int pre[maxn], pos[maxn];
int f[maxn];
int val[maxn][40];
int an[maxn];

int fid (int x) {
    if (x != f[x]) f[x] = fid(f[x]);
    return f[x];
}

void insert(int b[], int x){
    for(int i = 30; i >= 0; i--){
        if (x>>i&1){
            if (!b[i]) {b[i] = x; break;}
            else x ^= b[i];
        }
    }
}

void unit(int p1, int p2){
    int x = fid (p1), y = fid (p2);
    for(int i = 0; i <= 30; i++){
        if (val[y][i]) insert(val[x], val[y][i]);
    }
    f[y] = x;
}

int solve(int p){
    int years = 0;
    for(int i = 30; i >= 0; i--){
        if ((ans^val[p][i]) > ans) {
            ans ^= val[p][i];
        }
    }
    return ans;
}


int main() {
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    cin >> n;
    
    for(int i = 1; i <= n; i++) scanf("%d", &pre[i]);
    for(int i = 1; i <= n; i++) scanf("%d", &pos[i]);
    memset(f, 0, sizeof(f));
    int years = 0;
    for(int i = n; i >= 1; i--){
        int x = pos[i]; // position
        f[x] = x;
        insert(val[x], pre[x]);
        
        if (f[x-1]) unit(x, x-1);
        if (f[x+1]) unit(x, x+1);
        years = max(years, solve(x));
        an[i] = ans;
    }    
    for(int i = 1; i <= n; i++) printf("%d\n", an[i]);
    return 0;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324971503&siteId=291194637