Codeforces Round 882 (Div. 2) - C

发布时间 2023-07-07 19:32:29作者: Qiansui

C. Vampiric Powers, anyone?

题意:
给你n个数,你可以进行任意次操作,每次操作你可以从数组最后往前选择任意个连续的数并将其异或和的结果放置在数组末尾,问你操作过程中的元素最大值是多少
思路:
我们这么想,数组末尾一块的异或结果放在最后,如果再选这一块+新的一个,那么\(A\oplus A=0\),我们通过这样的操作就可以删去数组末尾,而异或的长度又是自己选择,那么最终的答案就是你选择一个区间,使得这个区间的异或和最大
但是\(1\le t \le 10000,1\le n \le 10^5\),所以\(O(n^2)\)肯定超时
注意到题目还给了个条件\(0 \le a_i \le 2^8\),所以$O(n*2^8) $ 则问题不大
那么怎么优化呢?其实就是从数值出发,反正前面哪组数异或出的值我们并不关心,所以暴力查询0~255是否出现在某个数的前缀异或和中即可
下见暴力代码

const int maxm=2e5+5,inf=0x3f3f3f3f,mod=998244353;
int n,a[maxm];

void solve(){
	cin>>n;
	a[0]=0;
	int ans=0,t=0;
	vector<bool> b(256,false);
	b[0]=true;
	for(int i=1;i<=n;++i){
		cin>>a[i];
		t^=a[i];
		for(int i=0;i<256;++i){
			if(b[i]){
				ans=max(ans,t^i);
			}
		}
		b[t]=true;
	}
	cout<<ans<<'\n';
	return ;
}

好像还有01trie树解决问题的方法,待学习[ ]