思路:
小范围暴力
大范围递归构造
构造方法:
solve(l, r) 表示使l 到 r 区间全变为0的方法
为了使反转次数小于等于n/3 + 12
我们只需要保证每次反转后区间长度减少值的期望为3就可以了
如果a[l] == 0, l++
如果a[r] == 0, r–
如果a[l] == 1 && a[l+1] == 1 && a[l+2] == 1, 反转这三个就可以啦, l += 3
如果a[l] == 1 && a[l+1] == 0 && a[l+2] == 1, 反转l, l+2, l+4这三个, l += 3
如果a[l] == 1 && a[l+1] == 0 && a[l+1] == 0, 反转l, l+3, l+6这三个, l += 3
从右区间减少同理
否则只剩下这种情况了:
1 1 0 …… 0 1 1
那么只需要根据区间长度的奇偶性
反转l , (l+r)/2, r 和 l+1 , (l+1+r-1)/2, r-1 或者 l, (l+r-1)/2, r-1 和 l+1 , (l+1+r)/2, r
然后 l += 3, r -= 3, 区间长度减少6
区间长度小于8的话就暴力
用二进制枚举所有的反转情况, 然后检查
代码:
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pli pair<LL, int>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head#define ck(l, x, y, z) a[l]==x&&a[l+1]==y&&a[l+2]==z
#define ckk(r, x, y, z) a[r]==x&&a[r-1]==y&&a[r-2]==z
const int N = 1e5 + ;
int a[N], tmp[N], n;
vector<piii> ans;
bool f = false;
void flip(int x, int y, int z) {
a[x] ^= ;
a[y] ^= ;
a[z] ^= ;
ans.pb({{x, y}, z});
}
void fflip(int x, int y) {
a[x] ^= ;
a[x+y>>] ^= ;
a[y] ^= ;
ans.pb({{x, x+y>>}, y});
}
void Flip(int x, int y) {
tmp[x] ^= ;
tmp[x+y>>] ^= ;
tmp[y] ^= ;
//ans.pb({{x, x+y>>1}, y});
}
void bruteforce(int l, int r) {
vector<pii> vc;
for (int i = l; i <= r; i++) {
for (int j = i+; j <= r; j += ) {
vc.pb({i, j});
}
}
int sz = vc.size();
for (int i = ; i < (<<sz); i++) {
for (int j = l; j <= r; j++) tmp[j] = a[j];
for (int j = ; j < sz; j++) {
if(i&(<<j)) {
Flip(vc[j].fi, vc[j].se);
}
}
bool ff = true;
for (int j = l; j <= r; j++) if(tmp[j]) {ff = false; break;}
if(ff) {
f = true;
for (int j = ; j < sz; j++) if(i&(<<j))ans.pb({{vc[j].fi, vc[j].fi + vc[j].se >> }, vc[j].se});
return ;
}
}
}
void solve(int l, int r) {
if(r - l + <= ) {
while(r-l+ < && l > ) l--;
while(r-l+ < && r < n) r++;
bruteforce(l, r);
return ;
}
if(a[l] == ) {
solve(l+, r);
return ;
}
if(a[r] == ) {
solve(l, r-);
return ;
}
if(ck(l, , , )) {
flip(l, l+, l+);
solve(l+, r);
return ;
}
if(ck(l, , , )) {
flip(l, l+, l+);
solve(l+, r);
return ;
}
if(ck(l, , , )) {
flip(l, l+, l+);
solve(l+, r);
return ;
}
if(ckk(r, , , )) {
flip(r, r-, r-);
solve(l, r-);
return ;
}
if(ckk(r, , , )) {
flip(r, r-, r-);
solve(l, r-);
return ;
}
if(ckk(r, , , )) {
flip(r, r-, r-);
solve(l, r-);
return ;
}
if((r-l+)&) {
fflip(l, r);
fflip(l+, r-);
solve(l+, r-);
return ;
}
else {
fflip(l, r-);
fflip(l+, r);
solve(l+, r-);
return ;
}
}
int main() {
int cnt = ;
scanf("%d", &n);
for (int i = ; i <= n; i++) scanf("%d", &a[i]);
solve(, n);
if(f) {
printf("YES\n");
printf("%d\n", (int)ans.size());
for (piii p : ans) printf("%d %d %d\n", p.fi.fi, p.fi.se, p.se);
}
else printf("NO\n");
return ;
}