「CF1438D」 Powerful Ksenia

「CF1438D」 Powerful Ksenia

题目大意

给定 \(n\) 个正整数,你可以任选三个数 \(a_i,a_j,a_k\),使这三个数都变为 \(a_i\oplus a_j\oplus a_k\)\(\oplus\) 代表异或)。

问是否能构造一种方案,使得在 \(n\) 次操作内使所有数相等。


构造题。

显然我们有这样两种方式:

  • 选择三个数 \(a,b,c\),将他们变成 \(d\)
  • 选择三个数 \(a,a,b\),将他们变为 \(b\)

这启发我们将 \((1,2,3),(3,4,5),(5,6,7),...\) 这样的三元组进行操作,这样若原数列长度为奇数,则一定能构造出一种方案使得所有数相等。

下面考虑原数列长度为偶数的情况。

注意到我们的操作不会让原数列所有数的异或和发生改变,即若原数列长度为偶数且存在一种方案让所有数相等,则其所有数异或和一定为 \(0\)

这可以作为我们判定是否有解的必要条件。

那么若所有数异或和为 \(0\),是否一定能构造出一种方案呢?

答案是肯定的。此时我们忽略掉数列的最后一个数,使其变为奇数长度的序列即可,由于数列异或和为 \(0\),且操作不会改变原数列异或和,故前 \(n-1\) 个数进行操作后得到的值一定等于数列的第 \(n\) 个数。

代码:

/*---Author:HenryHuang---*/
/*---Never Settle---*/
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int a[maxn],sum;
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	int n;cin>>n;
	for(int i=1;i<=n;++i) cin>>a[i],sum^=a[i];
	if(n%2==0){
		--n;
		if(sum) cout<<"NO\n",exit(0);
	}
	cout<<"YES\n";
	cout<<n-2<<'\n';
	for(int i=1;i+2<=n;i+=2) cout<<i<<' '<<i+1<<' '<<i+2<<'\n';
	for(int i=1;i+1<=n-3;i+=2) cout<<i<<' '<<i+1<<' '<<n<<'\n'; 
	return 0;
}
posted @ 2021-02-07 22:11  Henry__Huang  阅读(57)  评论(0编辑  收藏  举报