洛谷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;
}
posted @ 2020-09-16 20:20  srf  阅读(132)  评论(0编辑  收藏  举报