UOJ Logo Miaki的博客

博客

求助 seq 构造方案哪里挂掉了

2021-08-25 11:55:24 By Miaki

大概思路就是对于 $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;
}

评论

fhqTreap
.

发表评论

可以用@mike来提到mike这个用户,mike会被高亮显示。如果你真的想打“@”这个字符,请用“@@”。