D. Powerful Ksenia
题意:
给一个长为n的数组,在小于等于n种操作下使得数组的所有数相同,每次操作——选定三个不同的下标i,j,k,然后a[i]=a[j]=a[k]=a[i]^a[j]^a[k]
题解:
(1)对x,x,y操作,得到y,y,y
(2)n为奇数时,可如下操作:
先1 2 3 ,3 4 5,5 6 7, 7 8 9 。。。。
得到的数列大概是 x,x,y,y,z,z。。。。。k,k,k (前面两两一组,最后三个相同)
这样做的次数是(n-1)/2
然后n-4 n-3 n-2 , n-6 n-5 n-4 .......
这样所有数就相同了,而且这个数就是所有数的亦或值
(3)n为偶数,大胆猜想——如果本来就存在可行方案,拿前n-1个数做上述操作,最后的所所有数是相同的
(4)对(3)的证明
考虑一个数的每一位,我们知道异或后一个位上的结果是每个数在这个数上的1的个数的奇偶性(略微绕口)
那么,当n为偶数时,若存在可行方案,最后会有偶数个相同的数,那么各个位上的1的个数都为偶数,那么所有初始数的亦或值为0
结合(2)操作最后得到的数是所有数的异或值,易得(3)成立
#include<bits/stdc++.h>
using namespace std;
void cal(int n)
{
for(int i=3;i<=n;i+=2)printf("%d %d %d\n",i-2,i-1,i);
for(int i=n-4;i>0;i-=2)printf("%d %d %d\n",i,i+1,i+2);
}
int main()
{
int n,x;
long long sum=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&x),sum^=x;
if(n&1){
printf("YES\n");
printf("%d\n",n-2);
cal(n);
}
else{
if(sum==0){
printf("YES\n");
printf("%d\n",n-3);
cal(n-1);
}
else printf("NO\n");
}
return 0;
}