Operation(线性基)

Operation(线性基)

题目描述

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.

输入

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.

输出

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

样例输入

复制样例数据

1
3 3
0 1 2
0 1 1
1 3
0 3 4
样例输出
1
3

ps:还是模板。线性基讲解:https://oi-wiki.org/math/basis/


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include &lt;iostream>

#include &lt;cstdio>

using namespace std;

 

const int maxn = 1e6+10;

 

int pos[maxn][31];

int p[maxn][31];

int n,m;

int a[maxn];

 

void A(int x,int in){

    int xxx=in;

    for(int i=0;i&lt;=29;++i){

        p[in][i]=p[in-1][i];

        pos[in][i]=pos[in-1][i];

    }

    for(int i=29;i>=0;i--){

        if(x &amp; (1&lt;&lt;i)){

            if(!p[in][i]){

                p[in][i]=x;

                pos[in][i]=xxx;

                return ;

            }

            if(pos[in][i]&lt;xxx) {

                int t=x;

                x=p[in][i];

                p[in][i]=t;

                int tt=xxx;

                xxx=pos[in][i];

                pos[in][i]=tt;

            }

            x^=p[in][i];

        }

    }

}

 

int Q(int l,int r){

    int res=0;

    for(int i=29;i>=0;i--){

        if(pos[r][i]>=l&amp;&amp;(res^p[r][i])>res) res=res^p[r][i];

    }

    return res;

}

 

int main()

{

    //std::ios::sync_with_stdio(false);

    int t;

    scanf("%d",&amp;t);

    while(t--){

        int ans=0;

        int n,m;

        scanf("%d%d",&amp;n,&amp;m);

        for(int i=1;i&lt;=n;i++){

            scanf("%d",&amp;a[i]);

            A(a[i],i);

        }

        while(m--){

            int op;

            int l,r;

            scanf("%d",&amp;op);

            if(op==1) {

                int x;

                scanf("%d",&amp;x);

                n++;

                a[n]=x;

                a[n]^=ans;

                A(a[n],n);

            }

            else{

                scanf("%d%d",&amp;l,&amp;r);

                l=(l^ans)%n+1;

                r=(r^ans)%n+1;

                if(l>r) {

                    int t=l;

                    l=r;

                    r=t;

                }

                ans=Q(l,r);

                printf("%d\n",ans);

            }

        }

    }

    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值