zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    Magento2 观察者模式 之 插件
    Magento2 自定义生成日志函数
    magento 由于Httpd进程增多,导致CPU占用100%问题
    Magento composer 安装
    htaccess 的使用基本小节 For apache httpd
    设计便捷命令行工具列表
    docker-lnmp dockerfile
    使用Portainer管理Docker
    关于IIS站点最大并发量分析
    深入理解IIS的多线程工作机制
  • 原文地址:https://www.cnblogs.com/whisperlzw/p/11243293.html
Copyright © 2011-2022 走看看