/
洛谷P4839.cpp
123 lines (110 loc) · 2.14 KB
/
洛谷P4839.cpp
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
#define mem(a,b) memset(a,b,sizeof(a))
const int maxn=5e4+50;
int n,m;
struct Seg
{
int l,r;
ll base[40];
int mid(){return l+((r-l)>>1);}
void Insert(ll x)
{
for(int i=31;i >= 0;--i)
{
if((x>>i)&1)
{
if(!base[i])
{
base[i]=x;
return ;
}
x ^= base[i];
}
}
}
ll Max()
{
ll ans=0;
for(int i=31;i >= 0;--i)
ans=max(ans,ans^base[i]);
return ans;
}
}seg[maxn<<2];
void build(int l,int r,int pos)
{
seg[pos]={l,r};
mem(seg[pos].base,0);
if(l == r)
return ;
int mid=l+((r-l)>>1);
build(l,mid,ls(pos));
build(mid+1,r,rs(pos));
}
Seg Merge(Seg a,Seg b)///合并线性基a.base,b.base
{
Seg ans=a;
ans.r=b.r;
for(int i=31;i >= 0;--i)
if(b.base[i])
ans.Insert(b.base[i]);
return ans;
}
void update(int pos,int k,int x)
{
if(seg[pos].l == seg[pos].r)
{
seg[pos].Insert(x);
return ;
}
int mid=seg[pos].mid();
if(k <= mid)
update(ls(pos),k,x);
else
update(rs(pos),k,x);
seg[pos].Insert(x);///直接将x插入到pos的base中即可
}
Seg query(int pos,int l,int r)
{
if(seg[pos].l == l && seg[pos].r == r)
return seg[pos];
int mid=seg[pos].mid();
if(r <= mid)
return query(ls(pos),l,r);
else if(l > mid)
return query(rs(pos),l,r);
else
return Merge(query(ls(pos),l,mid),query(rs(pos),mid+1,r));
}
void Solve()
{
build(1,m,1);
while(n--)
{
int op;
scanf("%d",&op);
if(op == 1)
{
int k;
ll x;
scanf("%d%lld",&k,&x);
update(1,k,x);
}
else
{
int l,r;
scanf("%d%d",&l,&r);
Seg ans=query(1,l,r);
printf("%lld\n",ans.Max());
}
}
}
int main()
{
scanf("%d%d",&n,&m);
Solve();
return 0;
}