码迷,mamicode.com
首页 > 其他好文 > 详细

线性基+并查集

时间:2020-04-01 01:14:29      阅读:56      评论:0      收藏:0      [点我收藏+]

标签:clu   set   long   ++   return   type   lse   else   ==   

线性基+并查集

无效位置

#include <cstdio>
#include <cstring>
typedef long long LL;
LL ans[1000010], a[1000010], b[1000010], d[1000010][70], pre[1000010];
int findn(int x) {
    int p = x, tmp;
    while(x != pre[x]) x = pre[x];
    while(p != x) {
        tmp = pre[p];
        pre[p] = x;
        p = tmp;
    }
    return x;
}
void add(int x, int y) {
    int p = findn(x);
    int q = findn(y);
    if(p != q) pre[q] = p;
}
void ins(LL d[][70], int tmp, int x) {
    for(int j = 60; j >= 0; j--) {
        if(a[x] & (1LL << j)) {
            if(d[tmp][j]) a[x] ^= d[tmp][j];
            else {
                d[tmp][j] = a[x];
                break;
            }
        }
    }
}
int main() {
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) scanf("%lld", &a[i]);
    for(int i = 1; i <= n; i++) scanf("%lld", &b[i]);
    memset(pre, 0, sizeof(pre));
    LL maxn = 0;
    for(int i = n; i > 0; i--) {
        int x = b[i];
        pre[x] = x;
        if(pre[x-1] && pre[x+1]) {
            int tmp = findn(x-1);
            ins(d, tmp, x);
            add(x-1, x);
            int tmp1 = findn(x+1);
            add(x, x + 1);
            int tmp2 = findn(x);
            for(int j = 60; j >= 0; j--) {
                for(int k = 60; k >= 0; k--) {
                    if(d[tmp1][j] & (1LL << k)) {
                        if(d[tmp2][k]) d[tmp1][j] ^= d[tmp2][k];
                        else {
                            d[tmp2][k] = d[tmp1][j];
                            break;
                        }
                    }
                }
            }
        }
        else if(pre[x-1] && pre[x+1] == 0) {
            int tmp = findn(x-1);
            ins(d, tmp, x);
            add(x-1, x);
        }
        else if(pre[x-1] == 0 && pre[x+1]) {
            int tmp = findn(x+1);
            add(x+1, x);
            ins(d, tmp, x);
        }
        else {
            ins(d, x, x);
        }
        int tmp = findn(x);
        LL sum = 0;
        for(int j = 60; j >= 0; j--) {
            if((sum ^ d[tmp][j]) > sum) {
                    sum ^= d[tmp][j];
            }
        }
        if(sum > maxn) maxn = sum;
        ans[i] = maxn;
    }
    for(int i = 1; i <= n; i++) printf("%lld\n", ans[i]);
    return 0;
}

线性基+并查集

标签:clu   set   long   ++   return   type   lse   else   ==   

原文地址:https://www.cnblogs.com/fanshhh/p/12609656.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!