大概思路就是对于 $n>4$ 的情况看所有元素是否一样
如果一样且为 $0$ 那么无解,否则如果一样且不为 $0$ 直接对于 $\forall 1\le i \le n-2$,让其变为 $a_{i+1} \text{ xor } a_{i+2}$
特判一下如果 n%2==1
那么 $a_n=a_1 \text{ xor } a_3$
如果元素不一样就随便找一个相邻不一样的位置
然后钦定奇数位都变成这两个位置的异或值,暂时先不更新这两个位置
接着这两个位置中的偶数位就可以变成 $0$ 了,直接这两个是否包含 $a_1$,然后分情况讨论
$n \le 4$ 的情况我测了好像没什么问题就不说了
40 分真不知道挂哪里。。。。。。
#include <bits/stdc++.h>
using namespace std;
#define ls ((rt)<<1)
#define rs ((rt)<<1|1)
#define pc putchar
#define gc getchar
#define mp make_pair
#define pb push_back
#define int long long
#define uLL unsigned long long
template <typename T>
inline void read(T &ret) {
ret = 0; char ch = gc(); int f = 1;
while (!isdigit(ch) && ch^'-') ch = gc();
if (ch=='-') f = -1, ch = gc();
while (isdigit(ch)) {
ret = (ret<<1) + (ret<<3) + (ch^48);
ch = gc();
} ret *= f; return ;
}
template <typename T>
inline void print(T x) {
char buf[20]; int cnt = 0;
if (x<0) { pc('-'); x = ~x + 1; }
if (!x) pc(48);
while (x) buf[cnt++] = x%10^48, x /= 10;
while (cnt) pc(buf[--cnt]); return ;
}
template <typename T>
inline T qpow(T bas, T pw, T Md) {
T mult = 1;
while (pw) {
if (pw&1) mult = mult * bas % Md;
bas = bas * bas % Md;
pw >>= 1;
} return mult;
}
inline void fp() {
freopen("seq.in", "r", stdin);
freopen("seq.out", "w", stdout); return ;
}
struct Third { int x, y, z; };
vector <Third> ans;
vector <Third> wtf; bool chk;
const int N = 7e4 + 10;
int T, n, a[N], b[N];
void dfs(int cur) {
if (chk) return ;
for (int i=1; i<=n; ++i) b[i] = a[i];
for (int i=0; i<wtf.size(); ++i)
b[wtf[i].x] = b[wtf[i].y] ^ b[wtf[i].z];
if (b[1]==b[3] && b[1]^b[2]) {
print(wtf.size()); puts("");
for (int i=0; i<wtf.size(); ++i) {
print(wtf[i].x), pc(' ');
print(wtf[i].y), pc(' ');
print(wtf[i].z); puts("");
} chk = true; return ;
}
if (cur==4) return ;
for (int i=1; i<=3; ++i) {
for (int j=1; j<=3; ++j) {
for (int k=1; k<=3; ++k) {
if (i==j || i==k || j==k) continue;
wtf.pb((Third){i, j, k});
dfs(cur+1); wtf.pop_back();
}
}
} return ;
}
signed main() {
read(T); while (T--) {
read(n); ans.clear(); int sum = 0;
for (int i=1; i<=n; ++i)
read(a[i]), sum += a[i];
if (n==1) { puts("0"); continue; }
if (!sum) { puts("-1"); continue; }
if (n>4) {
bool eq = true;
for (int i=2; i<=n; ++i) eq &= (a[i]==a[i-1]);
if (eq) { for (int i=1; i<=n-2; i+=2)
ans.pb((Third){i, i+1, i+2});
if (n&1) ans.pb((Third){n, 1, 3});
print(ans.size()); puts("");
for (int i=0; i<ans.size(); ++i) {
print(ans[i].x), pc(' ');
print(ans[i].y), pc(' ');
print(ans[i].z); puts("");
} continue;
} int pos = 0;
for (int i=1; i<n; ++i)
if (a[i]^a[i+1]) { pos = i; break; }
for (int i=1; i<=n; i+=2) {
if (i==pos || i==pos+1) continue;
ans.pb((Third){i, pos, pos+1});
}
if (pos&1) {
if (pos==1) {
ans.pb((Third){2, 3, 5});
ans.pb((Third){1, 2, 3});
} else {
ans.pb((Third){pos+1, 1, 3});
ans.pb((Third){pos, 1, pos+1});
}
} else {
if (pos==2) {
ans.pb((Third){2, 1, 5});
ans.pb((Third){3, 1, 2});
} else {
ans.pb((Third){pos, 1, 3});
ans.pb((Third){pos+1, 1, pos});
}
}
for (int i=2; i<=n; i+=2) {
if (i==pos || i==pos+1) continue;
ans.pb((Third){i, 1, 3});
}
print(ans.size()); puts("");
for (int i=0; i<ans.size(); ++i) {
print(ans[i].x), pc(' ');
print(ans[i].y), pc(' ');
print(ans[i].z); puts("");
} continue;
} if (n==2) {
if (a[1]==a[2]) puts("-1");
else puts("0"); continue;
} if (n==4) {
bool tag = false;
if (a[1]==a[3] && a[2]==a[4]) tag = true;
for (int i=1; i<=3; ++i) tag &= (a[i]!=a[i+1]);
if (tag) { puts("0"); continue; }
if (a[1] ^ a[3]) {
ans.pb((Third){2, 1, 3});
ans.pb((Third){4, 1, 3});
ans.pb((Third){1, 2, 4});
ans.pb((Third){3, 2, 4});
} else if (a[2] ^ a[4]) {
ans.pb((Third){1, 2, 4});
ans.pb((Third){3, 2, 4});
ans.pb((Third){2, 1, 3});
ans.pb((Third){4, 1, 3});
} else if (a[2]==a[3]) {
ans.pb((Third){1, 2, 4});
ans.pb((Third){3, 2, 4});
} if (!ans.size()) { puts("-1"); continue; }
print(ans.size()); puts("");
for (int i=0; i<ans.size(); ++i) {
print(ans[i].x), pc(' ');
print(ans[i].y), pc(' ');
print(ans[i].z); puts("");
} continue;
} if (n==3) {
wtf.clear(); chk = false; dfs(1);
if (!chk) puts("-1");
}
}
return 0;
}