2019杭电多校第一场 Operation HDU - 6579

Posted smallhester

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2019杭电多校第一场 Operation HDU - 6579相关的知识,希望对你有一定的参考价值。

题意:给出一个序列,两种操作,求区间[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("*********\n")
#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\n", lastans);
             else 
                scanf("%d", &r);
                add(r xor lastans);
                n++;
            
        
    

 

以上是关于2019杭电多校第一场 Operation HDU - 6579的主要内容,如果未能解决你的问题,请参考以下文章

2019 杭电多校第一场

2019杭电多校第一场

[补]2019HDU杭电多校第一场A

[2019杭电多校第一场][hdu6582]Path

[2019杭电多校第一场][hdu6578]Blank

2019杭电多校第一场hdu6581 Vacation