zoukankan      html  css  js  c++  java
  • 2019杭电多校第一场 Operation HDU

    题意:给出一个序列,两种操作,求区间[l,r]的区间最大异或和,和在末尾添加一个数

    思路:强制在线,保存每个线性基的数值,接下去直接去搜第r个线性基,但要保持时间比l要大,新增了一个pos数组代表一个数插入时的时间戳,插入的时候如果可以替换那么就用之后的替换之前的,保证线性基中都是最新的元素,可以直接插入即可以直接插入

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<stack>
    #include<cstdlib>
    #include<queue>
    #include<set>
    #include<string.h>
    #include<vector>
    #include<deque>
    #include<map>
    using namespace std;
    #define INF 0x3f3f3f3f3f3f3f3f
    #define inf 0x3f3f3f3f
    #define eps 1e-4
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    typedef long long LL;
    typedef long long ll;
    const int maxn = 1e6 + 5;
    const int mod = 998244353;
    
    int sum[maxn][50],pos[maxn][50];  //sum数组是数字,pos数组是时间,一共有maxn个线性基,sum[i][j]表示第i个线性基
    int tot; //时间戳
    void add(int num) {
        tot++;
        for (int i = 0; i < 32; i++) {   //保留了每个时间的线性基
            sum[tot][i] = sum[tot - 1][i];
            pos[tot][i] = pos[tot - 1][i];
        }
        int now = tot;  //  当前时间戳
        for (int i = 32; i >= 0; i--) {
            if (num & (1LL << i)) {   //可以插入就直接插入
                if (sum[tot][i] == 0) {
                    sum[tot][i] = num;
                    pos[tot][i] = now;
                    break;
                }
                if (now > pos[tot][i]) {    //如果当前插入的数之前已经存在过,那么就需要替换
                    swap(now, pos[tot][i]);
                    swap(num, sum[tot][i]);
                }
                num ^= sum[tot][i];
            }
        }
    }
    int query(int l,int r) {    //直接访问的是第r个线性基
        int ans = 0;
        for (int i = 32; i >= 0; i--) {     //当前数的出现的时间戳比l大
            if (pos[r][i] >= l)
                ans = max(ans, ans xor sum[r][i]);
        }
        return ans;
    }
    int main() {
        int t;
        scanf("%d", &t);
        while (t--) {
            tot = 0;
            int lastans = 0;
            int n, m;
            scanf("%d %d", &n, &m);
            int num;
            for (int i = 0; i < n; i++) {
                scanf("%d", &num);
                add(num);
            }
            while (m--) {
                int op, l, r;
                scanf("%d", &op);
                if (op == 0) {
                    scanf("%d %d", &l, &r);
                    l = (l xor lastans) % n + 1;
                    r = (r xor lastans) % n + 1;
                    if (l > r) swap(l, r);
                    lastans = query(l, r);
                    printf("%d
    ", lastans);
                } else {
                    scanf("%d", &r);
                    add(r xor lastans);
                    n++;
                }
            }
        }
    }
  • 相关阅读:
    操作系统进程通信
    操作系统进程调度
    java中的变量
    java移位运算符
    String, StringBuffer, StringBuilder 的区别
    多线程相关问题汇总
    java内存管理与GC机制(二)
    java内存管理与GC机制(一)
    进程与线程的理解
    Liferay7使用maven引入第三方jar包
  • 原文地址:https://www.cnblogs.com/smallhester/p/11416498.html
Copyright © 2011-2022 走看看