• 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;
    }
    
  • 相关阅读:
    测试我的第一个随笔
    ORB-SLAM2初步
    STL map 简介
    day4-内置函数
    Python学习之路day4-函数高级特性、装饰器
    Python学习之路day3-函数
    Python学习之路day3-字符编码与转码
    Python学习之路day3-文件操作
    Python学习之路day3-集合
    Python学习之路【第二篇】-pyc简介、Python常用的数据类型及其用法和常用运算符
  • 原文地址:https://www.cnblogs.com/whisperlzw/p/11243293.html
Copyright © 2020-2023  润新知