洛谷P4585 [FJOI2015]火星商店问题 题解
直接线段树套\(Trie\)即可。
\(\Theta(n\log n \log a_i).\)
code :
#include <bits/stdc++.h>
using namespace std;
template <typename T> void read(T &x){
x = 0; int f = 1; char ch = getchar();
while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();}
while (isdigit(ch)) {x = x * 10 + ch - '0'; ch = getchar();}
x *= f;
}
inline void write(int x){if (x > 9) write(x/10); putchar(x%10+'0'); }
const int N = 100050,V = N * 300;
struct Trie{
int ch[V][2],mx[V],cnto;
inline void Ins(int &rt,int v,int t){
if (!rt) rt = ++cnto;
int i,now = rt,c; mx[rt] = max(mx[rt],t);
for (i = 16; i >= 0; --i){
c = v >> i & 1;
if (!ch[now][c]) ch[now][c] = ++cnto;
now = ch[now][c];
mx[now] = max(mx[now],t);
}
}/*
inline int copy(int x){
++cnto,ch[cnto][0] = ch[x][0],ch[cnto][1] = ch[x][1],mx[cnto] = mx[x];
return cnto;
}
inline int Ins2(int rt,int v,int t){
int i,c,o = copy(rt),now; mx[rt] = max(mx[rt],t);
for (now = o,i = 16; i >= 0; --i){
c = v >> i & 1;
ch[now][c] = copy(ch[now][c]);
now = ch[now][c];
mx[now] = max(mx[now],t);
}
return o;
}
*/
inline int query(int rt,int v,int t){
if (mx[rt] < t) return 0;
int i,c,now = rt,ans = v;
for (i = 16; i >= 0; --i){
c = 1 ^ (v >> i & 1);
if (ch[now][c] && mx[ch[now][c]] >= t) now = ch[now][c],ans ^= c * (1<<i);
else now = ch[now][c^1],ans ^= (c^1) * (1<<i);
}
return ans;
}
}T;
int n,m;
int pp,vv,tt,G[N<<2];
inline void Add(int o,int l,int r){
T.Ins(G[o],vv,tt);
if (l < r){ int mid = l+r>>1; if (pp <= mid) Add(o<<1,l,mid); else Add(o<<1|1,mid+1,r); }
}
int ll,rr,qans;
inline void Ask(int o,int l,int r){
if (ll <= l && rr >= r){ qans = max(qans,T.query(G[o],vv,tt)); return; }
int mid = l+r>>1; if (ll <= mid) Ask(o<<1,l,mid); if (rr > mid) Ask(o<<1|1,mid+1,r);
}
int Time;
int main(){
// cerr <<sizeof(Trie) * 1.0 /1024 /1024 << '\n';
int i,op;
read(n),read(m);
for (i = 1; i <= n; ++i) pp = i,read(vv),tt = 100000,Add(1,1,n);
while (m--){
read(op);
if (!op){
read(pp),read(vv),tt = ++Time; Add(1,1,n);
}
else{
qans = 0;
read(ll),read(rr),read(vv),read(tt),tt = max(1,Time-tt+1);
Ask(1,1,n);
cout << qans << '\n';
}
}
return 0;
}