题解 CF1438D 【Powerful Ksenia】
do_while_true · · 题解
\mathcal{Translate}
题目链接
给定长度为
\mathcal{Solution}
考虑一次操作带来了什么:
-
将三个数推平,也就是把任意三个数变成相等的一个数。
-
如果三个数中有两个相等,那么相当于把三个数都推平成除了那两个相等的第三个数。
1.是显然的,因为操作就是把它们三个推平。
2.是因为如果其中
此时对于
对于
首先有一个结论,一次操作不会对序列的总按位异或和产生改变。
设操作前按位异或和为
则原先序列
当
设前
\mathcal{Code}
//Code by do_while_true
#include<iostream>
#include<cstdio>
inline int read() {
int r = 0; bool w = 0; char ch = getchar();
while(ch < '0' || ch > '9') {
if(ch == '-') w = 1;
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
r = (r << 3) + (r << 1) + (ch ^ 48);
ch = getchar();
}
return w ? ~r + 1 : r;
}
const int N = 100010;
int n, a[N], sum;
signed main() {
n = read();
for(int i = 1; i <= n; ++i) a[i] = read(), sum ^= a[i];
if(!(n&1)) {
--n;
if(sum) {
puts("NO");
return 0;
}
}
puts("YES");
printf("%d\n", n-2);
for(int i = 1; i + 2 <= n; i += 2) printf("%d %d %d\n", i, i+1, i+2);
for(int i = 1; i + 1 <= n - 3; i += 2) printf("%d %d %d\n", i, i+1, n);
return 0;
}