2019 Multi-University Training Contest 1 1002 Operation HDU6579(线性基,贪心)

Operation

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1624    Accepted Submission(s): 526


 

Problem Description

There is an integer sequence a of length n and there are two kinds of operations:

  • 0 l r: select some numbers from al...ar so that their xor sum is maximum, and print the maximum value.
  • 1 x: append x to the end of the sequence and let n=n+1.

 

 

 

Input

There are multiple test cases. The first line of input contains an integer T(T≤10), indicating the number of test cases.
For each test case: 
The first line contains two integers n,m(1≤n≤5×105,1≤m≤5×105), the number of integers initially in the sequence and the number of operations.
The second line contains n integers a1,a2,...,an(0≤ai<230), denoting the initial sequence.
Each of the next m lines contains one of the operations given above.
It's guaranteed that ∑n≤106,∑m≤106,0≤x<230.
And operations will be encrypted. You need to decode the operations as follows, where lastans denotes the answer to the last type 0 operation and is initially zero: 
For every type 0 operation, let l=(l xor lastans)mod n + 1, r=(r xor lastans)mod n + 1, and then swap(l, r) if l>r.
For every type 1 operation, let x=x xor lastans.

 

 

Output

For each type 0 operation, please output the maximum xor sum in a single line.

 

 

Sample Input

 

1 3 3 0 1 2 0 1 1 1 3 0 3 4

 

 

Sample Output

 

1 3

 

 

Source

2019 Multi-University Training Contest 1

思路:首先需要理解线性基的基本概念,然后这个需要求区间异或和最大值,那么可以维护前缀线性基,并且保证每个前缀线性基都是从最右边到最左边,从最高位到最低位处理的,并且记录每个线性基中每个向量的位置(一定最靠右)。这样在求lr区间的线性基异或和最大值的时候,只要从r前缀线性基最高位开始,向下正常求取,并且保证每个向量的位置大于等于l,最终求得的线性基就一定是答案。

其他:本题还要求强制在线,第一遇到。

AC代码

//include <bits/stdc++.h>
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <stack>
#include <time.h>
#include <string.h>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define sdddd(x,y,z,k) scanf("%d%d%d%d", &x, &y, &z, &k)
#define sddd(x,y,z) scanf("%d%d%d", &x, &y, &z)
#define sdd(x,y) scanf("%d%d", &x, &y)
#define sd(x) scanf("%d", &x)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define mp Debug(x) printf("%d\n", &x);
#define pb push_back
#define ms(x, y) memset(x, y, sizeof x)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll MOD = 1e9+7;
const int maxn = 5e5+50;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
//typedef vector<ll> vec;
//typedef vector<vec> mat;
template <class T>
inline bool scan_d(T &ret) {
    char c; int sgn;
    if (c = getchar(), c == EOF) return 0;
    while (c != '-' && (c<'0' || c>'9')) c = getchar();
    sgn = (c == '-') ? -1 : 1;
    ret = (c == '-') ? 0 : (c - '0');
    while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
    ret *= sgn;
    return 1;
}
int maxbit = 31;
int n, m, t;
int a[maxn];
int P[maxn][35], POS[maxn][35];
void add(int r, int x)
{
    rep(i, 0, maxbit) P[r][i] = P[r-1][i], POS[r][i]  = POS[r-1][i];
    int tmp = 0;
    int k = r;
    per(i, maxbit, 0){
        //cout << (x>>i) << endl;
        if((x>>i)&1){
            if(!P[r][i]){
                P[r][i] = x;
                POS[r][i] = k;
                break;
            }else{
                if(k > POS[r][i]){
                    tmp = POS[r][i], POS[r][i] = k, k = tmp;
                    tmp = P[r][i], P[r][i] = x, x = tmp;
                }
                x ^= P[r][i];
            }
        }
    }
}
int main()
{
    scan_d(t);
    while(t--){
        scan_d(n); scan_d(m);
        int ta,tb,tc;
        int lastans = 0;
        rep(i, 1, n)
            scan_d(a[i]), add(i, a[i]);

        while(m--){
            scan_d(ta);
            if(ta) scan_d(tb), a[++n] = lastans^tb, add(n, a[n]);
            else{
                scan_d(tb); scan_d(tc);
                tb = (tb^lastans)%n+1;
                tc = (tc^lastans)%n+1;
                if(tb > tc)
                    swap(tb, tc);
                int ans = 0;

                per(i, maxbit, 0){
                    if(P[tc][i] && POS[tc][i] >= tb){
                        if((ans^P[tc][i]) > ans)
                            ans^=P[tc][i];
                    }
                }
                printf("%d\n", lastans = ans);
            }
        }
        rep(i, 0, n){
            rep(j, 0, maxbit){
                P[i][j] = POS[i][j] = 0;
            }
        }
    }
    return 0;
}
/*
6
3 1 5 2 4 6
6 3 4 5 2 1
*/

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值