zoukankan      html  css  js  c++  java
  • 线性基+并查集

    线性基+并查集

    无效位置

    #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
    ", ans[i]);
        return 0;
    }
    
  • 相关阅读:
    信号的调制
    是否产生latch
    带通采样定理
    傅里叶变换
    信号与傅里叶(下)
    滤波器的相位和信号的时延
    信号与傅里叶级数
    阅读应该是主动的
    Matlab笔记—函数
    网络搭建---IP地址的设置及ping的使用
  • 原文地址:https://www.cnblogs.com/fanshhh/p/12609656.html
Copyright © 2011-2022 走看看