1. 程式人生 > 實用技巧 >最大異或和

最大異或和

最大異或和

解題思路

這題是一道版題,學過可持久化字典樹的應該都會

Code

#include<algorithm>
#include<cstdio>
using namespace std;
const int N = 6e5 + 5;
int n,m,s[N],rt[N],ch[30 * N][2],sum[60 * N],tot = 0;

void update(int u,int v,int x)
{
	for (int i = 30; i >= 0; i--)
	{
		int c = (x >> i) & 1;
		sum[u] = sum[v] + 1;
		ch[u][c ^ 1] = ch[v][c ^ 1];
		ch[u][c] = ++ tot;
		u = ch[u][c],v = ch[v][c];
	}
	sum[u] = sum[v] + 1;
}
int query(int u,int v,int x)
{
	int res = 0;
	for (int i = 30; i >= 0; i--)
	{
		int c = (x >> i) & 1,k = sum[ch[u][c ^ 1]] - sum[ch[v][c ^ 1]];
		if (k) res |= 1 << i,u = ch[u][c ^ 1],v = ch[v][c ^ 1];
		else u = ch[u][c],v = ch[v][c];
	}
	return res;
}
int main()
{
	scanf("%d%d",&n,&m);
	for (int i = 1; i <= n; i++)
	{
		int q;
		scanf("%d",&q);
		s[i] = s[i - 1] ^ q;
	}
	for (int i = 1; i <= n; i++) rt[i] = ++tot,update(rt[i],rt[i - 1],s[i]);
	for (int i = 1; i <= m; i++)
	{
		char ch1[3];
		int q,p,c;
		scanf("%s",ch1);
		if (ch1[0] == 'A') 
			scanf("%d",&q),n++,s[n] = s[n - 1] ^ q,
			rt[n] = ++tot,update(rt[n],rt[n - 1],s[n]);
		if (ch1[0] == 'Q')
		{
			scanf("%d%d%d",&q,&p,&c);
			q--,p--;
			if (q == p && q == 0) printf("%d\n",s[n] ^ c);
			else printf("%d\n",query(rt[p],rt[max(0,q - 1)],s[n] ^ c));
		}
	}
}