• 2019杭电多校第一场hdu6579 Operation(线性基)


    Operation

    题目传送门

    解题思路

    把右边的数尽量往高位放,构造线性基的时候同时记录其在原序列中的位置,在可以插入的时候如果那个位置上存在的数字的位置比新放入的要小,就把旧的往后挤。用这种发现构造前缀线性基,求最大前缀和的时候只有忽略位置比l小的即可。

    代码如下

    #include <bits/stdc++.h>
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    
    inline int read(){
        int res = 0, w = 0; char ch = 0;
        while(!isdigit(ch)){
            w |= ch == '-', ch = getchar();
        }
        while(isdigit(ch)){
            res = (res << 3) + (res << 1) + (ch ^ 48);
            ch = getchar();
        }
        return w ? -res : res;
    }
    
    const int N = 1000005;
    
    int a[N];
    int b[N][40], pos[N][40];
    
    void insert(int k, int x)
    {
        for(int i = 30; i >= 0; i --){
            b[k][i] = b[k - 1][i];
            pos[k][i] = pos[k - 1][i];
        }
        int t = k;
        for(int i = 30; i >= 0; i --){
            if((x >> i) & 1){
                if(b[t][i]){
                    if(pos[t][i] < k){
                        swap(b[t][i], x);
                        swap(pos[t][i], k);
                    }
                    x ^= b[t][i];
                }
                else {
                    b[t][i] = x;
                    pos[t][i] = k;
                    break;
                }
            }
        }
    }
    
    int query(int l, int r)
    {
        int ans = 0;
        for(int i = 30; i >= 0; i --){
            if(pos[r][i] >= l){
                if((ans ^ b[r][i]) > ans)
                    ans ^= b[r][i];
            }
        }
        return ans;
    }
    
    int main()
    {
        int T;
        cin >> T;
        while(T --){
            int n, m;
            n = read(), m = read();
            for(int i = 1; i <= n; i ++){
                a[i] = read();
                insert(i, a[i]);
            }  
            int last = 0;
            for(int i = 1; i <= m; i ++){
                int opt;
                opt = read();
                if(opt == 0){
                    int l, r;
                    l = read(), r = read();
                    l = (l ^ last) % n + 1;
                    r = (r ^ last) % n + 1;
                    if(l > r)
                        swap(l, r);
                    last = query(l, r);
                    printf("%d
    ", last);
                }
                else {
                    int x = read();
                    ++n;
                    insert(n, x ^ last);
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    css自适应
    css居中
    js生成签名
    javascript与Android、IOS交互
    js截取路径参数
    js date对象
    js判断设备、浏览器类型
    live555实践
    关于django
    mysql的基本知识
  • 原文地址:https://www.cnblogs.com/whisperlzw/p/11243293.html
Copyright © 2020-2023  润新知