P4735 최대 XOR 및 영구 시도 템플릿 질문

주제를 보려면 여기를 클릭하십시오.

구간 내 위치에서 끝까지의 XOR 합계의 최대 값이 필요합니다. 변환 해 봅시다. S [i]는 첫 번째 i 위치의 XOR 결과, 즉 XOR 값의 접두사 합계를 나타냅니다.
따라서 제목 a [p] ^ a [p + 1] ^ ... a [n] ^ x = s [p-1] ^ s [n] ^ x. 따라서 질문은 val = s [n] ^ x 값이 주어지면 l-1 = <p <= r-1을 만족하는 위치 p를 찾아 s [p] ^ val 값을 가장 크게 만드는 것과 같습니다.
이 경우 trie를 지속적으로 만들기 만하면되며 간격이 법적 위치 (즉, 두 버전간에 법적 위치가 있는지 여부)를 요청할 때마다 cnt 배열을 사용하여 각 val에서 반대 위치의 간격 조건이 합법적인지 확인합니다. 간격 요구 사항 p를 달성하기 위해 트라이의 끝 노드에 해당하는 버전의 정보를 기록합니다.
마지막으로 해당 간격의 왼쪽 끝이 1이면 0에서 가장 큰 XOR 합계 일 수 있습니다. 따라서 삽입해야합니다. 작동 중에 노드 0의 삽입을 전처리하여이 문제를 해결하십시오.

특정 작업에 대한 코드 참조 :
알고리즘 경쟁 고급 가이드의 P252 페이지를 참조 할 수 있습니다 .

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int MAXN = 6e5+7;
//可持久化Trie
int n,m;
int trie[MAXN*24][2],root[MAXN<<1],cnt[MAXN*24],size;
int s[MAXN<<1];//异或和

void insert(int now,int pre,int k,int x)
{
    
    
	if(k < 0) return ;
	int i = (x>>k)&1;//把第k位拿上来
	trie[now][!i] = trie[pre][!i];//之前的都连在一起
	trie[now][i] = ++size;//新插入的单独开节点
	cnt[trie[now][i]] = cnt[trie[pre][i]]+1;//记录当前的版本
	insert(trie[now][i],trie[pre][i],k-1,x);//递归插入
}

int query(int r,int l,int k,int x)
{
    
    
	if(k < 0) return 0;
	int i = (x>>k)&1;
	if(cnt[trie[r][!i]] > cnt[trie[l][!i]])//代表这个区间可行
		return (1<<k) + query(trie[r][!i],trie[l][!i],k-1,x);
	else
		return query(trie[r][i],trie[l][i],k-1,x);
}

int main()
{
    
    
	scanf("%d%d",&n,&m);
	//要把0先插入trie中
	root[0] = ++size;
	insert(root[0],0,24,0);
	for(int i = 1;i <= n;i ++){
    
    
		int x;
		scanf("%d",&x);
		s[i] = s[i-1]^x;
		root[i] = ++size;
		insert(root[i],root[i-1],24,s[i]);
	}
	while(m--){
    
    
		char op;int l,r,x;
		cin>>op;
		switch(op){
    
    
			case 'A':
				scanf("%d",&x);
				n++;//在序列尾添加元素的话 就是在尾部申请一个新的节点
				s[n] = s[n-1]^x;
				root[n] = ++size;
				insert(root[n],root[n-1],24,s[n]);
				break;
			case 'Q':
				scanf("%d%d%d",&l,&r,&x);
				l--,r--;
				//printf("-----\n");
				int ans;
				if(l == 0) ans = query(root[r],0,24,s[n]^x);
				else ans = query(root[r],root[l-1],24,s[n]^x);
				//printf("-----\n");
				printf("%d\n",ans);
				break;
		}
	}
	return 0;
}

추천

출처blog.csdn.net/weixin_45672411/article/details/108487032