• 2019 Multi-University Training Contest 1


    魔改线性基

    强制在线的做法,需要维护一个前缀的线性基,每次新加入数的时候,要把靠右边的数提到线性基的高位

    这样维护的线性基,在查询区间异或和的时候,只需要把r为前缀的线性基出现为止大于l且异或之后和更大的数异或起来就行了,新套路!!

    #include <bits/stdc++.h>
    #define INF 0x3f3f3f3f
    #define full(a, b) memset(a, b, sizeof a)
    #define FAST_IO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
    using namespace std;
    typedef long long LL;
    inline int lowbit(int x){ return x & (-x); }
    inline int read(){
        int ret = 0, w = 0; char ch = 0;
        while(!isdigit(ch)){
            w |= ch == '-', ch = getchar();
        }
        while(isdigit(ch)){
            ret = (ret << 3) + (ret << 1) + (ch ^ 48);
            ch = getchar();
        }
        return w ? -ret : ret;
    }
    inline int lcm(int a, int b){ return a / __gcd(a, b) * b; }
    template <typename A, typename B, typename C>
    inline A fpow(A x, B p, C lyd){
        A ans = 1;
        for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
        return ans;
    }
    const int N = 1000005;
    int _, n, m, pos[N][32], l, r;
    LL b[N][32], val;
    
    int main(){
    
        for(scanf("%d", &_); _; _ --){
            scanf("%d%d", &n, &m);
            for(int i = 1; i <= n; i ++){
                scanf("%lld", &val);
                for(int j = 0; j <= 31; j ++)
                    b[i][j] = b[i - 1][j], pos[i][j] = pos[i - 1][j];
                int cur = i;
                for(int j = 31; j >= 0; j --){
                    if(val & (1LL << j)){
                        if(!b[i][j]){
                            b[i][j] = val, pos[i][j] = cur;
                            break;
                        }
                        else{
                            if(pos[i][j] < cur) swap(pos[i][j], cur), swap(b[i][j], val);
                            val ^= b[i][j];
                        }
                    }
                }
            }
            LL opt, l, r, cnt = n;
            LL val, ret = 0;
            while(m --){
                scanf("%lld", &opt);
                if(opt == 0){
                    scanf("%lld%lld", &l, &r);
                    l = (l ^ ret) % cnt + 1, r = (r ^ ret) % cnt + 1;
                    if(l > r) swap(l, r);
                    ret = 0;
                    for(int i = 31; i >= 0; i --){
                        if(pos[r][i] >= l && (ret ^ b[r][i]) > ret)
                            ret ^= b[r][i];
                    }
                    printf("%lld
    ", ret);
                }
                else{
                    scanf("%lld", &val);
                    val ^= ret, cnt ++;
                    for(int i = 0; i <= 31; i ++)
                        b[cnt][i] = b[cnt - 1][i], pos[cnt][i] = pos[cnt - 1][i];
                    int cur = cnt;
                    for(int i = 31; i >= 0; i --){
                        if(val & (1LL << i)){
                            if(!b[cnt][i]){
                                b[cnt][i] = val, pos[cnt][i] = cur;
                                break;
                            }
                            else{
                                if(pos[cnt][i] < cur) swap(pos[cnt][i], cur), swap(b[cnt][i], val);
                                val ^= b[cnt][i];
                            }
                        }
                    }
                }
            }
            for (int i=1;i<=n;++i)
                for (int j=30;j>=0;--j) b[i][j] = pos[i][j] =0;
        }
        return 0;
    }
    
  • 相关阅读:
    MySql中的变量定义
    mysql常用脚本
    Spring中依赖注入的使用和配置
    在linux下通过sh运行java程序
    linux下shell脚本学习
    eclipse导出jar包
    mysql中游标的使用
    netty中LengthFieldBasedFrameDecoder的使用
    网络游戏服务器架构(转)
    H2 database的使用
  • 原文地址:https://www.cnblogs.com/onionQAQ/p/11233709.html
Copyright © 2020-2023  润新知