「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;
}
在繁华中沉淀自我,在乱世中静静伫立,一笔一划,雕刻时光。