CF1516B

B. AGAGA XOOORRR

有时候比赛考的是审题。

题目中提到了:

he picks \(2\) adjacent elements

'adjacent' 没看到,浪费 1.5h,这场比赛凉凉了。

具体分析做法。

容易想到最后留下的数要么 \(2\) 个,要么 \(3\) 个。这很好证明。

如果有 \(n(n>3)\) 个数相等,那么我一定可以拉出来两个数,异或一下,变成 \(0\),然后随便搞到一个数身上。由于最后不可以只留下一个数,所以留下的数要么 \(2\) 个,要么 \(3\) 个。

\(2\) 个数的情况很好判断,只需要判断所有数异或起来是否等于 \(0\)

\(3\) 个数也很好做,注意到 \(N\) 的范围,我们可以直接枚举三个区间,利用好维护好的前缀和随便搞一下即可。

//Don't act like a loser.
//This code is written by huayucaiji
//You can only use the code for studying or finding mistakes
//Or,you'll be punished by Sakyamuni!!!
#include<bits/stdc++.h>
#define int long long
using namespace std;

int read() {
	char ch=getchar();
	int f=1,x=0;
	while(ch<'0'||ch>'9') {
		if(ch=='-')
			f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9') {
		x=x*10+ch-'0';
		ch=getchar();
	}
	return f*x;
}

int n;
int a[5000],s[5000]; 

void judge() {
	for(int i=1;i<=n;i++) {
		for(int j=i+1;j<n;j++) {
			if((s[j]^s[i])==s[i]&&s[i]==(s[n]^s[j]) ){
				puts("YES");
				return ;
			}
		}
	}
	puts("NO");
}

signed main() {
	int t=read();
	while(t--) {
		n=read();
		for(int i=1;i<=n;i++) {
			a[i]=read();
			s[i]=s[i-1]^a[i];
		}
		
		if(s[n]==0) {
			puts("YES");
			continue;
		}
		judge();
	}
	return 0;
}

如果没有相邻这个条件,可能要用到线性基。

原文地址:https://www.cnblogs.com/huayucaiji/p/CF1516B.html