Problem p02977 (C++)

Buggy submission (status: Time Limit Exceeded):
#pragma GCC optimize("O3")
#pragma GCC target("sse4")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;

typedef pair<int, int> pi;
typedef pair<ll, ll> pl;
typedef pair<ld, ld> pd;

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;

template <class T>
using Tree =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FORd(i, a, b) for (int i = (b)-1; i >= (a); i--)
#define F0Rd(i, a) for (int i = (a)-1; i >= 0; i--)
#define trav(a, x) for (auto &a : x)

#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound

#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rsz resize

const int MOD = 1000000007; // 998244353
const ll INF = 1e18;
const int MX = 200005;
const ld PI = 4 * atan((ld)1);

template <class T> void ckmin(T &a, T b) { a = min(a, b); }
template <class T> void ckmax(T &a, T b) { a = max(a, b); }

namespace input {
template <class T> void re(complex<T> &x);
template <class T1, class T2> void re(pair<T1, T2> &p);
template <class T> void re(vector<T> &a);
template <class T, size_t SZ> void re(array<T, SZ> &a);

template <class T> void re(T &x) { cin >> x; }
void re(double &x) {
  string t;
  re(t);
  x = stod(t);
}
void re(ld &x) {
  string t;
  re(t);
  x = stold(t);
}
template <class Arg, class... Args> void re(Arg &first, Args &...rest) {
  re(first);
  re(rest...);
}

template <class T> void re(complex<T> &x) {
  T a, b;
  re(a, b);
  x = cd(a, b);
}
template <class T1, class T2> void re(pair<T1, T2> &p) { re(p.f, p.s); }
template <class T> void re(vector<T> &a) { F0R(i, sz(a)) re(a[i]); }
template <class T, size_t SZ> void re(array<T, SZ> &a) { F0R(i, SZ) re(a[i]); }
} // namespace input

using namespace input;

namespace output {
template <class T1, class T2> void pr(const pair<T1, T2> &x);
template <class T, size_t SZ> void pr(const array<T, SZ> &x);
template <class T> void pr(const vector<T> &x);
template <class T> void pr(const set<T> &x);
template <class T1, class T2> void pr(const map<T1, T2> &x);

template <class T> void pr(const T &x) { cout << x; }
template <class Arg, class... Args>
void pr(const Arg &first, const Args &...rest) {
  pr(first);
  pr(rest...);
}

template <class T1, class T2> void pr(const pair<T1, T2> &x) {
  pr("{", x.f, ", ", x.s, "}");
}
template <class T> void prContain(const T &x) {
  pr("{");
  bool fst = 1;
  for (const auto &a : x)
    pr(!fst ? ", " : "", a), fst = 0; // const needed for vector<bool>
  pr("}");
}
template <class T, size_t SZ> void pr(const array<T, SZ> &x) { prContain(x); }
template <class T> void pr(const vector<T> &x) { prContain(x); }
template <class T> void pr(const set<T> &x) { prContain(x); }
template <class T1, class T2> void pr(const map<T1, T2> &x) { prContain(x); }

void ps() { pr("\n"); }
template <class Arg> void ps(const Arg &first) {
  pr(first);
  ps(); // no space at end of line
}
template <class Arg, class... Args>
void ps(const Arg &first, const Args &...rest) {
  pr(first, " ");
  ps(rest...); // print w/ spaces
}
} // namespace output

using namespace output;

namespace io {
void setIn(string s) { freopen(s.c_str(), "r", stdin); }
void setOut(string s) { freopen(s.c_str(), "w", stdout); }
void setIO(string s = "") {
  ios_base::sync_with_stdio(0);
  cin.tie(0); // fast I/O
  if (sz(s)) {
    setIn(s + ".in"), setOut(s + ".out");
  } // for USACO
}
} // namespace io

using namespace io;

template <class T> T invGeneral(T a, T b) {
  a %= b;
  if (a == 0)
    return b == 1 ? 0 : -1;
  T x = invGeneral(b, a);
  return x == -1 ? -1 : ((1 - (ll)b * x) / a + b) % b;
}

template <class T> struct modular {
  T val;
  explicit operator T() const { return val; }
  modular() { val = 0; }
  modular(const ll &v) {
    val = (-MOD <= v && v <= MOD) ? v : v % MOD;
    if (val < 0)
      val += MOD;
  }

  friend ostream &operator<<(ostream &os, const modular &a) {
    return os << a.val;
  }
  friend bool operator==(const modular &a, const modular &b) {
    return a.val == b.val;
  }
  friend bool operator!=(const modular &a, const modular &b) {
    return !(a == b);
  }

  modular operator-() const { return modular(-val); }
  modular &operator+=(const modular &m) {
    if ((val += m.val) >= MOD)
      val -= MOD;
    return *this;
  }
  modular &operator-=(const modular &m) {
    if ((val -= m.val) < 0)
      val += MOD;
    return *this;
  }
  modular &operator*=(const modular &m) {
    val = (ll)val * m.val % MOD;
    return *this;
  }
  friend modular pow(modular a, ll p) {
    modular ans = 1;
    for (; p; p /= 2, a *= a)
      if (p & 1)
        ans *= a;
    return ans;
  }
  friend modular inv(const modular &a) {
    auto i = invGeneral(a.val, MOD);
    assert(i != -1);
    return i;
  } // equivalent to return exp(b,MOD-2) if MOD is prime
  modular &operator/=(const modular &m) { return (*this) *= inv(m); }

  friend modular operator+(modular a, const modular &b) { return a += b; }
  friend modular operator-(modular a, const modular &b) { return a -= b; }
  friend modular operator*(modular a, const modular &b) { return a *= b; }

  friend modular operator/(modular a, const modular &b) { return a /= b; }
};

typedef modular<int> mi;
typedef pair<mi, mi> pmi;
typedef vector<mi> vmi;
typedef vector<pmi> vpmi;

int N, val[MX];
vi adj[MX];
vpi ed;

void addEdge(int a, int b) { ed.pb({a, b}); }

void dfs(int a, int b) {
  trav(t, adj[a]) if (t != b) {
    val[t] = val[a];
    if (t > N)
      val[t] ^= t - N;
    else
      val[t] ^= t;
    dfs(t, a);
  }
}

void solve() {
  ed.clear();
  int k = 1;
  while (2 * k + 1 <= N)
    k = 2 * k + 1;
  if (N == 1 || N == k + 1) {
    ps("No");
    return;
  }
  vi seq = {1};
  int des = -1;
  if (N % 2 == 0) {
    des = N - k;
    seq.pb(des);
  }
  FOR(i, 2, k + 1) if (i != des) seq.pb(i);
  int z = sz(seq);
  F0R(i, z) seq.pb(seq[i] + N);
  F0R(i, sz(seq) - 1) addEdge(seq[i], seq[i + 1]);
  for (int i = k + 1; i + 1 <= N; i += 2) {
    addEdge(1, i);
    addEdge(i, i + 1);
    addEdge(1, i + 1 + N);
    addEdge(i + 1 + N, i + N);
  }
  if (N % 2 == 0) {
    addEdge(N, k + 1);
    addEdge(des, 2 * N);
  }
  ps("Yes");
  assert(sz(ed) == 2 * N - 1);
  FOR(i, 1, MX) adj[i].clear();
  trav(t, ed) {
    ps(t.f, t.s);
    adj[t.f].pb(t.s), adj[t.s].pb(t.f);
  }
  FOR(i, 1, N + 1) {
    val[i] = i;
    dfs(i, 0);
    assert(val[N + i] == i);
  }
}

int main() {
  setIO();
  re(N);
  solve();
  /*FOR(z,1,17) {
      N = z; ps(N);
      solve();
  }*/
}

/* stuff you should look for
 * int overflow, array bounds
 * special cases (n=1?), set tle
 * do smth instead of nothing and stay organized
 */

Fixed submission:
#pragma GCC optimize("O3")
#pragma GCC target("sse4")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;

typedef pair<int, int> pi;
typedef pair<ll, ll> pl;
typedef pair<ld, ld> pd;

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;

template <class T>
using Tree =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FORd(i, a, b) for (int i = (b)-1; i >= (a); i--)
#define F0Rd(i, a) for (int i = (a)-1; i >= 0; i--)
#define trav(a, x) for (auto &a : x)

#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound

#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rsz resize

const int MOD = 1000000007; // 998244353
const ll INF = 1e18;
const int MX = 200005;
const ld PI = 4 * atan((ld)1);

template <class T> void ckmin(T &a, T b) { a = min(a, b); }
template <class T> void ckmax(T &a, T b) { a = max(a, b); }

namespace input {
template <class T> void re(complex<T> &x);
template <class T1, class T2> void re(pair<T1, T2> &p);
template <class T> void re(vector<T> &a);
template <class T, size_t SZ> void re(array<T, SZ> &a);

template <class T> void re(T &x) { cin >> x; }
void re(double &x) {
  string t;
  re(t);
  x = stod(t);
}
void re(ld &x) {
  string t;
  re(t);
  x = stold(t);
}
template <class Arg, class... Args> void re(Arg &first, Args &...rest) {
  re(first);
  re(rest...);
}

template <class T> void re(complex<T> &x) {
  T a, b;
  re(a, b);
  x = cd(a, b);
}
template <class T1, class T2> void re(pair<T1, T2> &p) { re(p.f, p.s); }
template <class T> void re(vector<T> &a) { F0R(i, sz(a)) re(a[i]); }
template <class T, size_t SZ> void re(array<T, SZ> &a) { F0R(i, SZ) re(a[i]); }
} // namespace input

using namespace input;

namespace output {
template <class T1, class T2> void pr(const pair<T1, T2> &x);
template <class T, size_t SZ> void pr(const array<T, SZ> &x);
template <class T> void pr(const vector<T> &x);
template <class T> void pr(const set<T> &x);
template <class T1, class T2> void pr(const map<T1, T2> &x);

template <class T> void pr(const T &x) { cout << x; }
template <class Arg, class... Args>
void pr(const Arg &first, const Args &...rest) {
  pr(first);
  pr(rest...);
}

template <class T1, class T2> void pr(const pair<T1, T2> &x) {
  pr("{", x.f, ", ", x.s, "}");
}
template <class T> void prContain(const T &x) {
  pr("{");
  bool fst = 1;
  for (const auto &a : x)
    pr(!fst ? ", " : "", a), fst = 0; // const needed for vector<bool>
  pr("}");
}
template <class T, size_t SZ> void pr(const array<T, SZ> &x) { prContain(x); }
template <class T> void pr(const vector<T> &x) { prContain(x); }
template <class T> void pr(const set<T> &x) { prContain(x); }
template <class T1, class T2> void pr(const map<T1, T2> &x) { prContain(x); }

void ps() { pr("\n"); }
template <class Arg> void ps(const Arg &first) {
  pr(first);
  ps(); // no space at end of line
}
template <class Arg, class... Args>
void ps(const Arg &first, const Args &...rest) {
  pr(first, " ");
  ps(rest...); // print w/ spaces
}
} // namespace output

using namespace output;

namespace io {
void setIn(string s) { freopen(s.c_str(), "r", stdin); }
void setOut(string s) { freopen(s.c_str(), "w", stdout); }
void setIO(string s = "") {
  ios_base::sync_with_stdio(0);
  cin.tie(0); // fast I/O
  if (sz(s)) {
    setIn(s + ".in"), setOut(s + ".out");
  } // for USACO
}
} // namespace io

using namespace io;

template <class T> T invGeneral(T a, T b) {
  a %= b;
  if (a == 0)
    return b == 1 ? 0 : -1;
  T x = invGeneral(b, a);
  return x == -1 ? -1 : ((1 - (ll)b * x) / a + b) % b;
}

template <class T> struct modular {
  T val;
  explicit operator T() const { return val; }
  modular() { val = 0; }
  modular(const ll &v) {
    val = (-MOD <= v && v <= MOD) ? v : v % MOD;
    if (val < 0)
      val += MOD;
  }

  friend ostream &operator<<(ostream &os, const modular &a) {
    return os << a.val;
  }
  friend bool operator==(const modular &a, const modular &b) {
    return a.val == b.val;
  }
  friend bool operator!=(const modular &a, const modular &b) {
    return !(a == b);
  }

  modular operator-() const { return modular(-val); }
  modular &operator+=(const modular &m) {
    if ((val += m.val) >= MOD)
      val -= MOD;
    return *this;
  }
  modular &operator-=(const modular &m) {
    if ((val -= m.val) < 0)
      val += MOD;
    return *this;
  }
  modular &operator*=(const modular &m) {
    val = (ll)val * m.val % MOD;
    return *this;
  }
  friend modular pow(modular a, ll p) {
    modular ans = 1;
    for (; p; p /= 2, a *= a)
      if (p & 1)
        ans *= a;
    return ans;
  }
  friend modular inv(const modular &a) {
    auto i = invGeneral(a.val, MOD);
    assert(i != -1);
    return i;
  } // equivalent to return exp(b,MOD-2) if MOD is prime
  modular &operator/=(const modular &m) { return (*this) *= inv(m); }

  friend modular operator+(modular a, const modular &b) { return a += b; }
  friend modular operator-(modular a, const modular &b) { return a -= b; }
  friend modular operator*(modular a, const modular &b) { return a *= b; }

  friend modular operator/(modular a, const modular &b) { return a /= b; }
};

typedef modular<int> mi;
typedef pair<mi, mi> pmi;
typedef vector<mi> vmi;
typedef vector<pmi> vpmi;

int N, val[MX];
vi adj[MX];
vpi ed;

void addEdge(int a, int b) { ed.pb({a, b}); }

void dfs(int a, int b) {
  trav(t, adj[a]) if (t != b) {
    val[t] = val[a];
    if (t > N)
      val[t] ^= t - N;
    else
      val[t] ^= t;
    dfs(t, a);
  }
}

void solve() {
  ed.clear();
  int k = 1;
  while (2 * k + 1 <= N)
    k = 2 * k + 1;
  if (N == 1 || N == k + 1) {
    ps("No");
    return;
  }
  vi seq = {1};
  int des = -1;
  if (N % 2 == 0) {
    des = N - k;
    seq.pb(des);
  }
  FOR(i, 2, k + 1) if (i != des) seq.pb(i);
  int z = sz(seq);
  F0R(i, z) seq.pb(seq[i] + N);
  F0R(i, sz(seq) - 1) addEdge(seq[i], seq[i + 1]);
  for (int i = k + 1; i + 1 <= N; i += 2) {
    addEdge(1, i);
    addEdge(i, i + 1);
    addEdge(1, i + 1 + N);
    addEdge(i + 1 + N, i + N);
  }
  if (N % 2 == 0) {
    addEdge(N, k + 1);
    addEdge(des, 2 * N);
  }
  ps("Yes");
  assert(sz(ed) == 2 * N - 1);
  FOR(i, 1, MX) adj[i].clear();
  trav(t, ed) {
    ps(t.f, t.s);
    adj[t.f].pb(t.s), adj[t.s].pb(t.f);
  }
  /*FOR(i,1,N+1) {
      val[i] = i; dfs(i,0);
      assert(val[N+i] == i);
  }*/
}

int main() {
  setIO();
  re(N);
  solve();
  /*FOR(z,1,17) {
      N = z; ps(N);
      solve();
  }*/
}

/* stuff you should look for
 * int overflow, array bounds
 * special cases (n=1?), set tle
 * do smth instead of nothing and stay organized
 */