QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#719433#8523. Puzzle IImaspyTL 689ms6800kbC++2325.6kb2024-11-07 01:05:202024-11-07 01:05:21

Judging History

This is the latest submission verdict.

  • [2024-11-07 01:05:21]
  • Judged
  • Verdict: TL
  • Time: 689ms
  • Memory: 6800kb
  • [2024-11-07 01:05:20]
  • Submitted

answer

#line 1 "/home/maspy/compro/library/my_template.hpp"
#if defined(LOCAL)
#include <my_template_compiled.hpp>
#else

// https://codeforces.com/blog/entry/96344
#pragma GCC optimize("Ofast,unroll-loops")
// いまの CF だとこれ入れると動かない?
// #pragma GCC target("avx2,popcnt")

#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
using i128 = __int128;
using u128 = unsigned __int128;
using f128 = __float128;

template <class T>
constexpr T infty = 0;
template <>
constexpr int infty<int> = 1'010'000'000;
template <>
constexpr ll infty<ll> = 2'020'000'000'000'000'000;
template <>
constexpr u32 infty<u32> = infty<int>;
template <>
constexpr u64 infty<u64> = infty<ll>;
template <>
constexpr i128 infty<i128> = i128(infty<ll>) * 2'000'000'000'000'000'000;
template <>
constexpr double infty<double> = infty<ll>;
template <>
constexpr long double infty<long double> = infty<ll>;

using pi = pair<ll, ll>;
using vi = vector<ll>;
template <class T>
using vc = vector<T>;
template <class T>
using vvc = vector<vc<T>>;
template <class T>
using vvvc = vector<vvc<T>>;
template <class T>
using vvvvc = vector<vvvc<T>>;
template <class T>
using vvvvvc = vector<vvvvc<T>>;
template <class T>
using pq = priority_queue<T>;
template <class T>
using pqg = priority_queue<T, vector<T>, greater<T>>;

#define vv(type, name, h, ...) vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define vvv(type, name, h, w, ...) vector<vector<vector<type>>> name(h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...) \
  vector<vector<vector<vector<type>>>> name(a, vector<vector<vector<type>>>(b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))

// https://trap.jp/post/1224/
#define FOR1(a) for (ll _ = 0; _ < ll(a); ++_)
#define FOR2(i, a) for (ll i = 0; i < ll(a); ++i)
#define FOR3(i, a, b) for (ll i = a; i < ll(b); ++i)
#define FOR4(i, a, b, c) for (ll i = a; i < ll(b); i += (c))
#define FOR1_R(a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR2_R(i, a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR3_R(i, a, b) for (ll i = (b)-1; i >= ll(a); --i)
#define overload4(a, b, c, d, e, ...) e
#define overload3(a, b, c, d, ...) d
#define FOR(...) overload4(__VA_ARGS__, FOR4, FOR3, FOR2, FOR1)(__VA_ARGS__)
#define FOR_R(...) overload3(__VA_ARGS__, FOR3_R, FOR2_R, FOR1_R)(__VA_ARGS__)

#define FOR_subset(t, s) for (ll t = (s); t >= 0; t = (t == 0 ? -1 : (t - 1) & (s)))
#define all(x) x.begin(), x.end()
#define len(x) ll(x.size())
#define elif else if

#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define fi first
#define se second

#define stoi stoll

int popcnt(int x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(ll x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }
int popcnt_mod_2(int x) { return __builtin_parity(x); }
int popcnt_mod_2(u32 x) { return __builtin_parity(x); }
int popcnt_mod_2(ll x) { return __builtin_parityll(x); }
int popcnt_mod_2(u64 x) { return __builtin_parityll(x); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2)
int topbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(ll x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
int topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2)
int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(ll x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }

template <typename T>
T floor(T a, T b) {
  return a / b - (a % b && (a ^ b) < 0);
}
template <typename T>
T ceil(T x, T y) {
  return floor(x + y - 1, y);
}
template <typename T>
T bmod(T x, T y) {
  return x - y * floor(x, y);
}
template <typename T>
pair<T, T> divmod(T x, T y) {
  T q = floor(x, y);
  return {q, x - q * y};
}

template <typename T, typename U>
T SUM(const vector<U> &A) {
  T sm = 0;
  for (auto &&a: A) sm += a;
  return sm;
}

#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define LB(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define UB(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define UNIQUE(x) sort(all(x)), x.erase(unique(all(x)), x.end()), x.shrink_to_fit()

template <typename T>
T POP(deque<T> &que) {
  T a = que.front();
  que.pop_front();
  return a;
}
template <typename T>
T POP(pq<T> &que) {
  T a = que.top();
  que.pop();
  return a;
}
template <typename T>
T POP(pqg<T> &que) {
  T a = que.top();
  que.pop();
  return a;
}
template <typename T>
T POP(vc<T> &que) {
  T a = que.back();
  que.pop_back();
  return a;
}

template <typename F>
ll binary_search(F check, ll ok, ll ng, bool check_ok = true) {
  if (check_ok) assert(check(ok));
  while (abs(ok - ng) > 1) {
    auto x = (ng + ok) / 2;
    (check(x) ? ok : ng) = x;
  }
  return ok;
}
template <typename F>
double binary_search_real(F check, double ok, double ng, int iter = 100) {
  FOR(iter) {
    double x = (ok + ng) / 2;
    (check(x) ? ok : ng) = x;
  }
  return (ok + ng) / 2;
}

template <class T, class S>
inline bool chmax(T &a, const S &b) {
  return (a < b ? a = b, 1 : 0);
}
template <class T, class S>
inline bool chmin(T &a, const S &b) {
  return (a > b ? a = b, 1 : 0);
}

// ? は -1
vc<int> s_to_vi(const string &S, char first_char) {
  vc<int> A(S.size());
  FOR(i, S.size()) { A[i] = (S[i] != '?' ? S[i] - first_char : -1); }
  return A;
}

template <typename T, typename U>
vector<T> cumsum(vector<U> &A, int off = 1) {
  int N = A.size();
  vector<T> B(N + 1);
  FOR(i, N) { B[i + 1] = B[i] + A[i]; }
  if (off == 0) B.erase(B.begin());
  return B;
}

// stable sort
template <typename T>
vector<int> argsort(const vector<T> &A) {
  vector<int> ids(len(A));
  iota(all(ids), 0);
  sort(all(ids), [&](int i, int j) { return (A[i] == A[j] ? i < j : A[i] < A[j]); });
  return ids;
}

// A[I[0]], A[I[1]], ...
template <typename T>
vc<T> rearrange(const vc<T> &A, const vc<int> &I) {
  vc<T> B(len(I));
  FOR(i, len(I)) B[i] = A[I[i]];
  return B;
}

template <typename T, typename... Vectors>
void concat(vc<T> &first, const Vectors &... others) {
  vc<T> &res = first;
  (res.insert(res.end(), others.begin(), others.end()), ...);
}
#endif
#line 1 "/home/maspy/compro/library/other/io.hpp"
#define FASTIO
#include <unistd.h>

// https://judge.yosupo.jp/submission/21623
namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf
uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
  char num[10000][4];
  constexpr Pre() : num() {
    for (int i = 0; i < 10000; i++) {
      int n = i;
      for (int j = 3; j >= 0; j--) {
        num[i][j] = n % 10 | '0';
        n /= 10;
      }
    }
  }
} constexpr pre;

inline void load() {
  memcpy(ibuf, ibuf + pil, pir - pil);
  pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
  pil = 0;
  if (pir < SZ) ibuf[pir++] = '\n';
}

inline void flush() {
  fwrite(obuf, 1, por, stdout);
  por = 0;
}

void rd(char &c) {
  do {
    if (pil + 1 > pir) load();
    c = ibuf[pil++];
  } while (isspace(c));
}

void rd(string &x) {
  x.clear();
  char c;
  do {
    if (pil + 1 > pir) load();
    c = ibuf[pil++];
  } while (isspace(c));
  do {
    x += c;
    if (pil == pir) load();
    c = ibuf[pil++];
  } while (!isspace(c));
}

template <typename T>
void rd_real(T &x) {
  string s;
  rd(s);
  x = stod(s);
}

template <typename T>
void rd_integer(T &x) {
  if (pil + 100 > pir) load();
  char c;
  do
    c = ibuf[pil++];
  while (c < '-');
  bool minus = 0;
  if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
    if (c == '-') { minus = 1, c = ibuf[pil++]; }
  }
  x = 0;
  while ('0' <= c) { x = x * 10 + (c & 15), c = ibuf[pil++]; }
  if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
    if (minus) x = -x;
  }
}

void rd(int &x) { rd_integer(x); }
void rd(ll &x) { rd_integer(x); }
void rd(i128 &x) { rd_integer(x); }
void rd(u32 &x) { rd_integer(x); }
void rd(u64 &x) { rd_integer(x); }
void rd(u128 &x) { rd_integer(x); }
void rd(double &x) { rd_real(x); }
void rd(long double &x) { rd_real(x); }
void rd(f128 &x) { rd_real(x); }

template <class T, class U>
void rd(pair<T, U> &p) {
  return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T>
void rd_tuple(T &t) {
  if constexpr (N < std::tuple_size<T>::value) {
    auto &x = std::get<N>(t);
    rd(x);
    rd_tuple<N + 1>(t);
  }
}
template <class... T>
void rd(tuple<T...> &tpl) {
  rd_tuple(tpl);
}

template <size_t N = 0, typename T>
void rd(array<T, N> &x) {
  for (auto &d: x) rd(d);
}
template <class T>
void rd(vc<T> &x) {
  for (auto &d: x) rd(d);
}

void read() {}
template <class H, class... T>
void read(H &h, T &... t) {
  rd(h), read(t...);
}

void wt(const char c) {
  if (por == SZ) flush();
  obuf[por++] = c;
}
void wt(const string s) {
  for (char c: s) wt(c);
}
void wt(const char *s) {
  size_t len = strlen(s);
  for (size_t i = 0; i < len; i++) wt(s[i]);
}

template <typename T>
void wt_integer(T x) {
  if (por > SZ - 100) flush();
  if (x < 0) { obuf[por++] = '-', x = -x; }
  int outi;
  for (outi = 96; x >= 10000; outi -= 4) {
    memcpy(out + outi, pre.num[x % 10000], 4);
    x /= 10000;
  }
  if (x >= 1000) {
    memcpy(obuf + por, pre.num[x], 4);
    por += 4;
  } else if (x >= 100) {
    memcpy(obuf + por, pre.num[x] + 1, 3);
    por += 3;
  } else if (x >= 10) {
    int q = (x * 103) >> 10;
    obuf[por] = q | '0';
    obuf[por + 1] = (x - q * 10) | '0';
    por += 2;
  } else
    obuf[por++] = x | '0';
  memcpy(obuf + por, out + outi + 4, 96 - outi);
  por += 96 - outi;
}

template <typename T>
void wt_real(T x) {
  ostringstream oss;
  oss << fixed << setprecision(15) << double(x);
  string s = oss.str();
  wt(s);
}

void wt(int x) { wt_integer(x); }
void wt(ll x) { wt_integer(x); }
void wt(i128 x) { wt_integer(x); }
void wt(u32 x) { wt_integer(x); }
void wt(u64 x) { wt_integer(x); }
void wt(u128 x) { wt_integer(x); }
void wt(double x) { wt_real(x); }
void wt(long double x) { wt_real(x); }
void wt(f128 x) { wt_real(x); }

template <class T, class U>
void wt(const pair<T, U> val) {
  wt(val.first);
  wt(' ');
  wt(val.second);
}
template <size_t N = 0, typename T>
void wt_tuple(const T t) {
  if constexpr (N < std::tuple_size<T>::value) {
    if constexpr (N > 0) { wt(' '); }
    const auto x = std::get<N>(t);
    wt(x);
    wt_tuple<N + 1>(t);
  }
}
template <class... T>
void wt(tuple<T...> tpl) {
  wt_tuple(tpl);
}
template <class T, size_t S>
void wt(const array<T, S> val) {
  auto n = val.size();
  for (size_t i = 0; i < n; i++) {
    if (i) wt(' ');
    wt(val[i]);
  }
}
template <class T>
void wt(const vector<T> val) {
  auto n = val.size();
  for (size_t i = 0; i < n; i++) {
    if (i) wt(' ');
    wt(val[i]);
  }
}

void print() { wt('\n'); }
template <class Head, class... Tail>
void print(Head &&head, Tail &&... tail) {
  wt(head);
  if (sizeof...(Tail)) wt(' ');
  print(forward<Tail>(tail)...);
}

// gcc expansion. called automaticall after main.
void __attribute__((destructor)) _d() { flush(); }
} // namespace fastio
using fastio::read;
using fastio::print;
using fastio::flush;

#if defined(LOCAL)
#define SHOW(...) SHOW_IMPL(__VA_ARGS__, SHOW6, SHOW5, SHOW4, SHOW3, SHOW2, SHOW1)(__VA_ARGS__)
#define SHOW_IMPL(_1, _2, _3, _4, _5, _6, NAME, ...) NAME
#define SHOW1(x) print(#x, "=", (x)), flush()
#define SHOW2(x, y) print(#x, "=", (x), #y, "=", (y)), flush()
#define SHOW3(x, y, z) print(#x, "=", (x), #y, "=", (y), #z, "=", (z)), flush()
#define SHOW4(x, y, z, w) print(#x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w)), flush()
#define SHOW5(x, y, z, w, v) print(#x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", (v)), flush()
#define SHOW6(x, y, z, w, v, u) print(#x, "=", (x), #y, "=", (y), #z, "=", (z), #w, "=", (w), #v, "=", (v), #u, "=", (u)), flush()
#else
#define SHOW(...)
#endif

#define INT(...)   \
  int __VA_ARGS__; \
  read(__VA_ARGS__)
#define LL(...)   \
  ll __VA_ARGS__; \
  read(__VA_ARGS__)
#define U32(...)   \
  u32 __VA_ARGS__; \
  read(__VA_ARGS__)
#define U64(...)   \
  u64 __VA_ARGS__; \
  read(__VA_ARGS__)
#define STR(...)      \
  string __VA_ARGS__; \
  read(__VA_ARGS__)
#define CHAR(...)   \
  char __VA_ARGS__; \
  read(__VA_ARGS__)
#define DBL(...)      \
  double __VA_ARGS__; \
  read(__VA_ARGS__)

#define VEC(type, name, size) \
  vector<type> name(size);    \
  read(name)
#define VV(type, name, h, w)                     \
  vector<vector<type>> name(h, vector<type>(w)); \
  read(name)

void YES(bool t = 1) { print(t ? "YES" : "NO"); }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { print(t ? "Yes" : "No"); }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { print(t ? "yes" : "no"); }
void no(bool t = 1) { yes(!t); }
#line 3 "main.cpp"

#line 2 "/home/maspy/compro/library/ds/splaytree/splaytree.hpp"

/*
update でちゃんと prod が計算されてくれれば prod は op(lprod,x,rprod) でなくてもよい.
*/

// Node 型を別に定義して使う
template <typename Node>
struct SplayTree {
  Node *pool;
  const int NODES;
  int pid;
  using np = Node *;
  using X = typename Node::value_type;
  using A = typename Node::operator_type;
  vc<np> FREE;

  SplayTree(int NODES) : NODES(NODES), pid(0) { pool = new Node[NODES]; }
  ~SplayTree() { delete[] pool; }

  void free_subtree(np c) {
    if (!c) return;
    auto dfs = [&](auto &dfs, np c) -> void {
      if (c->l) dfs(dfs, c->l);
      if (c->r) dfs(dfs, c->r);
      FREE.eb(c);
    };
    dfs(dfs, c);
  }

  void reset() {
    pid = 0;
    FREE.clear();
  }

  np new_root() { return nullptr; }

  np new_node(const X &x) {
    assert(!FREE.empty() || pid < NODES);
    np n = (FREE.empty() ? &(pool[pid++]) : POP(FREE));
    Node::new_node(n, x);
    return n;
  }

  np new_node(const vc<X> &dat) {
    auto dfs = [&](auto &dfs, int l, int r) -> np {
      if (l == r) return nullptr;
      if (r == l + 1) return new_node(dat[l]);
      int m = (l + r) / 2;
      np l_root = dfs(dfs, l, m);
      np r_root = dfs(dfs, m + 1, r);
      np root = new_node(dat[m]);
      root->l = l_root, root->r = r_root;
      if (l_root) l_root->p = root;
      if (r_root) r_root->p = root;
      root->update();
      return root;
    };
    return dfs(dfs, 0, len(dat));
  }

  u32 get_size(np root) { return (root ? root->size : 0); }

  np merge(np l_root, np r_root) {
    if (!l_root) return r_root;
    if (!r_root) return l_root;
    assert((!l_root->p) && (!r_root->p));
    splay_kth(r_root, 0); // splay したので prop 済
    r_root->l = l_root;
    l_root->p = r_root;
    r_root->update();
    return r_root;
  }
  np merge3(np a, np b, np c) { return merge(merge(a, b), c); }
  np merge4(np a, np b, np c, np d) { return merge(merge(merge(a, b), c), d); }

  pair<np, np> split(np root, u32 k) {
    assert(!root || !root->p);
    if (k == 0) return {nullptr, root};
    if (k == (root->size)) return {root, nullptr};
    splay_kth(root, k - 1);
    np right = root->r;
    root->r = nullptr, right->p = nullptr;
    root->update();
    return {root, right};
  }
  tuple<np, np, np> split3(np root, u32 l, u32 r) {
    np nm, nr;
    tie(root, nr) = split(root, r);
    tie(root, nm) = split(root, l);
    return {root, nm, nr};
  }
  tuple<np, np, np, np> split4(np root, u32 i, u32 j, u32 k) {
    np d;
    tie(root, d) = split(root, k);
    auto [a, b, c] = split3(root, i, j);
    return {a, b, c, d};
  }

  // 部分木が区間 [l,r) に対応するようなノードを作って返す
  // そのノードが root になるわけではないので、
  // このノードを参照した後にすぐに splay して根に持ち上げること
  void goto_between(np &root, u32 l, u32 r) {
    if (l == 0 && r == root->size) return;
    if (l == 0) {
      splay_kth(root, r);
      root = root->l;
      return;
    }
    if (r == root->size) {
      splay_kth(root, l - 1);
      root = root->r;
      return;
    }
    splay_kth(root, r);
    np rp = root;
    root = rp->l;
    root->p = nullptr;
    splay_kth(root, l - 1);
    root->p = rp;
    rp->l = root;
    rp->update();
    root = root->r;
  }

  vc<X> get_all(const np &root) {
    vc<X> res;
    auto dfs = [&](auto &dfs, np root) -> void {
      if (!root) return;
      root->prop();
      dfs(dfs, root->l);
      res.eb(root->get());
      dfs(dfs, root->r);
    };
    dfs(dfs, root);
    return res;
  }

  X get(np &root, u32 k) {
    assert(root == nullptr || !root->p);
    splay_kth(root, k);
    return root->get();
  }

  void set(np &root, u32 k, const X &x) {
    assert(root != nullptr && !root->p);
    splay_kth(root, k);
    root->set(x);
  }

  void multiply(np &root, u32 k, const X &x) {
    assert(root != nullptr && !root->p);
    splay_kth(root, k);
    root->multiply(x);
  }

  X prod(np &root, u32 l, u32 r) {
    assert(root == nullptr || !root->p);
    using Mono = typename Node::Monoid_X;
    if (l == r) return Mono::unit();
    assert(0 <= l && l < r && r <= root->size);
    goto_between(root, l, r);
    X res = root->prod;
    splay(root, true);
    return res;
  }

  X prod(np &root) {
    assert(root == nullptr || !root->p);
    using Mono = typename Node::Monoid_X;
    return (root ? root->prod : Mono::unit());
  }

  void apply(np &root, u32 l, u32 r, const A &a) {
    if (l == r) return;
    assert(0 <= l && l < r && r <= root->size);
    goto_between(root, l, r);
    root->apply(a);
    splay(root, true);
  }
  void apply(np &root, const A &a) {
    if (!root) return;
    root->apply(a);
  }

  void reverse(np &root, u32 l, u32 r) {
    assert(root == nullptr || !root->p);
    if (l == r) return;
    assert(0 <= l && l < r && r <= root->size);
    goto_between(root, l, r);
    root->reverse();
    splay(root, true);
  }
  void reverse(np root) {
    if (!root) return;
    root->reverse();
  }

  void rotate(Node *n) {
    // n を根に近づける。prop, update は rotate の外で行う。
    Node *pp, *p, *c;
    p = n->p;
    pp = p->p;
    if (p->l == n) {
      c = n->r;
      n->r = p;
      p->l = c;
    } else {
      c = n->l;
      n->l = p;
      p->r = c;
    }
    if (pp && pp->l == p) pp->l = n;
    if (pp && pp->r == p) pp->r = n;
    n->p = pp;
    p->p = n;
    if (c) c->p = p;
  }

  void prop_from_root(np c) {
    if (!c->p) {
      c->prop();
      return;
    }
    prop_from_root(c->p);
    c->prop();
  }

  void splay(Node *me, bool prop_from_root_done) {
    // これを呼ぶ時点で、me の祖先(me を除く)は既に prop 済であることを仮定
    // 特に、splay 終了時点で me は upd / prop 済である
    if (!prop_from_root_done) prop_from_root(me);
    me->prop();
    while (me->p) {
      np p = me->p;
      np pp = p->p;
      if (!pp) {
        rotate(me);
        p->update();
        break;
      }
      bool same = (p->l == me && pp->l == p) || (p->r == me && pp->r == p);
      if (same) rotate(p), rotate(me);
      if (!same) rotate(me), rotate(me);
      pp->update(), p->update();
    }
    // me の update は最後だけでよい
    me->update();
  }

  void splay_kth(np &root, u32 k) {
    assert(0 <= k && k < (root->size));
    while (1) {
      root->prop();
      u32 sl = (root->l ? root->l->size : 0);
      if (k == sl) break;
      if (k < sl)
        root = root->l;
      else {
        k -= sl + 1;
        root = root->r;
      }
    }
    splay(root, true);
  }

  // check(x), 左側のノード全体が check を満たすように切る
  template <typename F>
  pair<np, np> split_max_right(np root, F check) {
    if (!root) return {nullptr, nullptr};
    assert(!root->p);
    np c = find_max_right(root, check);
    if (!c) {
      splay(root, true);
      return {nullptr, root};
    }
    splay(c, true);
    np right = c->r;
    if (!right) return {c, nullptr};
    right->p = nullptr;
    c->r = nullptr;
    c->update();
    return {c, right};
  }

  // check(x, cnt), 左側のノード全体が check を満たすように切る
  template <typename F>
  pair<np, np> split_max_right_cnt(np root, F check) {
    if (!root) return {nullptr, nullptr};
    assert(!root->p);
    np c = find_max_right_cnt(root, check);
    if (!c) {
      splay(root, true);
      return {nullptr, root};
    }
    splay(c, true);
    np right = c->r;
    if (!right) return {c, nullptr};
    right->p = nullptr;
    c->r = nullptr;
    c->update();
    return {c, right};
  }

  // 左側のノード全体の prod が check を満たすように切る
  template <typename F>
  pair<np, np> split_max_right_prod(np root, F check) {
    if (!root) return {nullptr, nullptr};
    assert(!root->p);
    np c = find_max_right_prod(root, check);
    if (!c) {
      splay(root, true);
      return {nullptr, root};
    }
    splay(c, true);
    np right = c->r;
    if (!right) return {c, nullptr};
    right->p = nullptr;
    c->r = nullptr;
    c->update();
    return {c, right};
  }

  template <typename F>
  np find_max_right(np root, const F &check) {
    // 最後に見つけた ok の点、最後に探索した点
    np last_ok = nullptr, last = nullptr;
    while (root) {
      last = root;
      root->prop();
      if (check(root->x)) {
        last_ok = root;
        root = root->r;
      } else {
        root = root->l;
      }
    }
    splay(last, true);
    return last_ok;
  }

  template <typename F>
  np find_max_right_cnt(np root, const F &check) {
    // 最後に見つけた ok の点、最後に探索した点
    np last_ok = nullptr, last = nullptr;
    ll n = 0;
    while (root) {
      last = root;
      root->prop();
      ll ns = (root->l ? root->l->size : 0);
      if (check(root->x, n + ns + 1)) {
        last_ok = root;
        n += ns + 1;
        root = root->r;
      } else {
        root = root->l;
      }
    }
    splay(last, true);
    return last_ok;
  }

  template <typename F>
  np find_max_right_prod(np root, const F &check) {
    using Mono = typename Node::Monoid_X;
    X prod = Mono::unit();
    // 最後に見つけた ok の点、最後に探索した点
    np last_ok = nullptr, last = nullptr;
    while (root) {
      last = root;
      root->prop();
      np tmp = root->r;
      root->r = nullptr;
      root->update();
      X lprod = Mono::op(prod, root->prod);
      root->r = tmp;
      root->update();
      if (check(lprod)) {
        prod = lprod;
        last_ok = root;
        root = root->r;
      } else {
        root = root->l;
      }
    }
    splay(last, true);
    return last_ok;
  }
};
#line 2 "/home/maspy/compro/library/ds/splaytree/splaytree_basic.hpp"

namespace SplayTreeNodes {
template <typename S>
struct Node_Basic {
  using value_type = S;
  using operator_type = int;
  using np = Node_Basic *;

  np p, l, r;
  bool rev;
  S x;
  u32 size;

  static void new_node(np n, const S &x) {
    n->p = n->l = n->r = nullptr;
    n->x = x, n->size = 1, n->rev = 0;
  }

  void update() {
    size = 1;
    if (l) { size += l->size; }
    if (r) { size += r->size; }
  }

  void prop() {
    if (rev) {
      if (l) { l->rev ^= 1, swap(l->l, l->r); }
      if (r) { r->rev ^= 1, swap(r->l, r->r); }
      rev = 0;
    }
  }

  // update, prop 以外で呼ばれるものは、splay 後であることが想定されている。
  // したがってその時点で update, prop 済であることを仮定してよい。
  S get() { return x; }
  void set(const S &xx) {
    x = xx;
    update();
  }
  void reverse() {
    swap(l, r);
    rev ^= 1;
  }
};
template <typename S>
using SplayTree_Basic = SplayTree<Node_Basic<S>>;
} // namespace SplayTreeNodes

using SplayTreeNodes::SplayTree_Basic;
#line 5 "main.cpp"

/*
aX, |X|=k
Yb, |Y|=k-1

aYb
X

Xb
aY

2回でひとつもってこれる
多い方からスタートしておく
*/

struct Data {
  int N, K;
  int idx = 0;
  deque<int> L, R;
  Data(int N, int K, vc<int> A) : N(N), K(K) {
    FOR(i, K) L.eb(A[i]);
    FOR(i, K, N) R.eb(A[i]);
  }
  void rot() {
    ++idx;
    idx %= N;
    L.emplace_back(POP(R));
    R.emplace_back(POP(L));
  }
  void debug() {
    vc<int> S(all(L));
    vc<int> T(all(R));
    SHOW(S, T);
  }
};

void solve() {
  LL(N, K);
  vc<int> X, Y;
  {
    STR(A, B);
    int b = count(all(A), 'B');
    int c = count(all(A), 'C');
    if (b > c) {
      for (auto& x: A) x = 'B' ^ 'C' ^ x;
      for (auto& x: B) x = 'B' ^ 'C' ^ x;
    }
    for (auto& x: A) X.eb(x == 'B');
    for (auto& x: B) Y.eb(x == 'B');
  }

  int n = SUM<int>(X);
  Data A(N, K, X), B(N, K, Y);
  vc<pi> ANS;

  FOR(n) {
    while (A.L[0] != 1) A.rot();
    while (B.L.back() != 0) B.rot();
    A.debug();
    B.debug();
    ANS.eb(A.idx + 1, B.idx);
    ANS.eb(A.idx, B.idx);
    A.L.pop_front();
    A.L.push_back(POP(A.R));
    A.R.push_front(0);
    B.L.pop_back();
    B.L.push_front(1);
  }
  print(len(ANS));
  for (auto& [a, b]: ANS) print(1 + a % N, 1 + b % N);
}

signed main() { solve(); }

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3576kb

input:

6 3
BCCBCC
BBCBBC

output:

4
2 1
1 1
4 4
3 4

result:

ok moves = 4

Test #2:

score: 0
Accepted
time: 0ms
memory: 3620kb

input:

2 1
BC
BC

output:

2
2 2
1 2

result:

ok moves = 2

Test #3:

score: 0
Accepted
time: 0ms
memory: 3640kb

input:

2 1
BB
CC

output:

0

result:

ok moves = 0

Test #4:

score: 0
Accepted
time: 0ms
memory: 3700kb

input:

2 1
CC
BB

output:

0

result:

ok moves = 0

Test #5:

score: 0
Accepted
time: 0ms
memory: 3632kb

input:

3 1
CCC
BBB

output:

0

result:

ok moves = 0

Test #6:

score: 0
Accepted
time: 0ms
memory: 3868kb

input:

3 1
CBC
BCB

output:

2
3 2
2 2

result:

ok moves = 2

Test #7:

score: 0
Accepted
time: 0ms
memory: 3644kb

input:

3 2
BBB
CCC

output:

0

result:

ok moves = 0

Test #8:

score: 0
Accepted
time: 0ms
memory: 3648kb

input:

3 2
BCB
BCC

output:

2
3 3
2 3

result:

ok moves = 2

Test #9:

score: 0
Accepted
time: 0ms
memory: 3644kb

input:

4 2
CCCB
BBCB

output:

2
1 2
4 2

result:

ok moves = 2

Test #10:

score: 0
Accepted
time: 0ms
memory: 3652kb

input:

9 6
CCCBCCCBB
BBBCBBBCC

output:

6
5 3
4 3
8 4
7 4
8 1
7 1

result:

ok moves = 6

Test #11:

score: 0
Accepted
time: 0ms
memory: 3700kb

input:

21 3
CCCCBBCBCCCCCCCBCCCCC
BBCCBCBBBBBBBBBCBBBBB

output:

8
6 1
5 1
6 2
5 2
7 4
6 4
17 14
16 14

result:

ok moves = 8

Test #12:

score: 0
Accepted
time: 0ms
memory: 3700kb

input:

49 41
CBCCBCCBCCBCCBCCCBBCCBCBBCCCBBCCBCBCBCBCCCCBCBCCB
BCCCCBCBBBBCBCBBBBBCBBBBCCCCBCBBCBBCBBBBCBCBCBBBC

output:

38
3 1
2 1
5 3
4 3
7 5
6 5
9 9
8 9
11 13
10 13
14 15
13 15
14 16
13 16
16 17
15 17
17 20
16 20
17 30
16 30
20 32
19 32
20 38
19 38
22 45
21 45
23 46
22 46
24 48
23 48
25 49
24 49
30 2
29 2
32 7
31 7
35 13
34 13

result:

ok moves = 38

Test #13:

score: 0
Accepted
time: 0ms
memory: 3696kb

input:

114 8
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

output:

0

result:

ok moves = 0

Test #14:

score: 0
Accepted
time: 0ms
memory: 3740kb

input:

266 28
CBBCBBCCCCBCBBCBBBCBCBCBCBBCBCBBCCCCBCCCCCBCCBBCCBBCBCBBCCCCCCBBBCCCBCCBCBBCCCBCCCCCCBCBBCCCBCBBCCBCBBBCBCCCBBCBCCCCBBCBBCBBCCBBCCCCCBBCCCBCCCCCCCCBBBBBBCBCCBCCCCBBCBBBBCBCCCCCCCBCBBCBCCCCCCCCCCCBBBBCCCCBCBCCCBCCCCCCCCCBCBCCCBBBCCCBCCBCBBCBCCCCCCBCBCCCCBCBCCBCCCCBCB
CCBCBCBBCBCBBCBCCCBBBCBCBB...

output:

206
3 6
2 6
3 14
2 14
4 21
3 21
4 22
3 22
8 24
7 24
9 30
8 30
9 33
8 33
10 34
9 34
10 38
9 38
10 39
9 39
11 44
10 44
12 45
11 45
13 47
12 47
14 49
13 49
14 51
13 51
15 53
14 53
18 55
17 55
20 57
19 57
27 59
26 59
41 61
40 61
44 63
43 63
44 68
43 68
47 69
46 69
47 72
46 72
48 73
47 73
50 74
49 74
50 ...

result:

ok moves = 206

Test #15:

score: 0
Accepted
time: 0ms
memory: 3724kb

input:

620 443
BBBBBBCBBBCBBCBCBCBBBBCCCBCCBCBBBBBBCCCBBBCCBBCBCBCBBCCCCBCBBCBCCCCBBBBBBCCCCCBBBBCCBCBBBBBCBCBBCBCBCCCCBCBBCBBBCBBBCCCBCCCBBBBBCCBBCCBBBCCBCCBCBBCBCCCCCCCCCBCBCBBBCBBCBBCBBBBBBBCCBBBBBBBBBBCBBCBBCBBCCCBBCCBBBBCCCBBBBBBCBBBBBBBBCBBCBCBBBCCBBBBCCBBBCBCBCBBBBBCBBCBBBBCBBBBCCBBBCBBBBBCBBCCCCBCC...

output:

484
8 1
7 1
11 2
10 2
13 3
12 3
14 6
13 6
15 8
14 8
19 11
18 11
19 14
18 14
19 15
18 15
20 20
19 20
20 26
19 26
21 27
20 27
27 28
26 28
27 34
26 34
27 36
26 36
30 37
29 37
30 43
29 43
32 44
31 44
33 45
32 45
34 47
33 47
36 49
35 49
36 52
35 52
36 57
35 57
36 59
35 59
37 60
36 60
39 62
38 62
40 64
39...

result:

ok moves = 484

Test #16:

score: 0
Accepted
time: 1ms
memory: 3756kb

input:

1446 646
CCCBCCCCCCCBBCCBBCCCCBBCCCBBCCCCCCCCCCCCCCCBCCCCCCCCBBCCBBCCCBCBBBCCCCBBCCCCCCCCCCCBCBCCCBBCCCCBBCBCBCCCCCCCBCCCCCCCBCCBCBBCCCCCCCCCCCCBCCCBCCCCCCBCCCBCCCCCBBCCCBBCCCBBBCCBCCBCCBBBCBCBCCCCBCBCCCBCCCCBBCCCCCCCBCCCCBCCCBBBCCCBCCBBCCCCBCCCBBCBCCCCCBBCCBCCCCCCBCCCCCCCCCCCCCCBCCCCCBCBCCCCBCCCCCB...

output:

874
5 3
4 3
12 4
11 4
12 5
11 5
14 6
13 6
14 8
13 8
18 11
17 11
18 15
17 15
21 19
20 19
21 20
20 20
36 23
35 23
44 24
43 24
44 25
43 25
46 26
45 26
46 27
45 27
49 30
48 30
50 33
49 33
50 36
49 36
50 38
49 38
54 42
53 42
54 46
53 46
65 48
64 48
66 49
65 49
69 50
68 50
69 51
68 51
73 65
72 65
73 67
72...

result:

ok moves = 874

Test #17:

score: 0
Accepted
time: 1ms
memory: 3860kb

input:

3374 2755
BCBBCBBBCBBBBBBBBBCCBBBBBBBCCBBCBBCBBBBBCBBBBBBBBCBBBBBBBBBBBBCBBBCCBBBBCBBBBBCBBBBBCBBBBCBBBBBBBBBCBBBBBBBBBBBCBBBBBBBCBBBBBBBBBBCCBBBBBBBBBCBBCBBBCBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCBBBCBBCBBBBBBBBBBBBBBCCBCBCBCBBBBCBBBCBBBBBBBBCBBCBCBBCBCCBBBBBBBBBBBCCBBBBBBBBBBBBBBBBBCBBBBBBBBBBB...

output:

1216
3 6
2 6
5 11
4 11
8 21
7 21
17 22
16 22
17 28
16 28
24 29
23 29
24 40
23 40
26 62
25 62
28 63
27 63
33 65
32 65
41 77
40 77
53 83
52 83
56 93
55 93
56 109
55 109
60 115
59 115
65 119
64 119
70 121
69 121
74 124
73 124
83 126
82 126
94 130
93 130
101 133
100 133
111 134
110 134
111 135
110 135
1...

result:

ok moves = 1216

Test #18:

score: 0
Accepted
time: 7ms
memory: 4028kb

input:

7872 7827
BCBBCBCBBCCBCBBBCCCBBBBBBBCBBBBCCBCCBCBBBBBBCBBCBBBCCCBBBCCCCBCBBBBCBBCCBBBBCCBBCBBBCBCBBCBCBBCCBBBCCBBBBCCBBCBBBBBBCBBBBBBBBCCBBCCCCBCCCBBCCCBBCBCBBBCBBBBCBBBBCBCBBBCCBBCCCCBBBCBBCCBBBBBBCBBBBCCCBBBCCCBBCCCBBBBBBCCBBBCCCCBBBCBBCBCCBBBCCCCBCBBCCBBBBCCBBBCBBCBBBCBBBCBBBBCCBBBBBCCBCBCBBBBBBB...

output:

5928
3 1
2 1
5 4
4 4
6 5
5 5
8 7
7 7
8 9
7 9
9 14
8 14
12 17
11 17
12 19
11 19
12 20
11 20
19 21
18 21
23 23
22 23
23 26
22 26
24 29
23 29
24 30
23 30
25 32
24 32
31 37
30 37
33 38
32 38
36 42
35 42
36 44
35 44
36 45
35 45
39 48
38 48
39 54
38 54
39 57
38 57
39 58
38 58
40 59
39 59
44 70
43 70
46 71...

result:

ok moves = 5928

Test #19:

score: 0
Accepted
time: 15ms
memory: 4264kb

input:

18368 17997
CBBBBBBBBBBCBBBBBBBBBBBBBBCBBCCBBBBBBBBBBBBBCBCBBBBBBBBCBBBBBCBBBBBBBBBBBBBBCBBBBBBBBBBCBBBCBCBBBBBCBCBBCBBBBBBBBBBBBBCCCBBBBBBCBBBBCBCBBCBBBBBCBBBBBBBCCBBBBCCBCBBBBBBBBBBBBCBBBBBBBBCBCBBBBBBBBCBCBBBBBBBBBBBCBBBBCCBBBBBBBCBBBBBBBBBBBBBBBCCBBCBCBBCBCBBBCBBBBBBBBBBBBBCBBCBBBBBBBCCCBBBBBBBB...

output:

7330
2 1
1 1
12 2
11 2
26 8
25 8
28 18
27 18
28 24
27 24
41 35
40 35
42 36
41 36
50 38
49 38
55 50
54 50
69 51
68 51
79 53
78 53
82 54
81 54
83 55
82 55
88 56
87 56
89 59
88 59
91 65
90 65
104 67
103 67
104 80
103 80
104 83
103 83
110 87
109 87
114 100
113 100
115 104
114 104
117 115
116 115
122 129...

result:

ok moves = 7330

Test #20:

score: 0
Accepted
time: 49ms
memory: 4876kb

input:

42858 28689
CCCCCCCCCCCCCCCCCCCCBCCCBBCCCBCCCCCCCCCBCCCCCCCBCCCBCCCCCBCCCCCCCCBCCBCCBCCCCCCCCCCCCCCCCCBCCCCCCCCCBCCCCBCCCCCCCCCCCCCCCCCCCCCCCCCCCCBCCCCCCCCCCCCCCCCCBBCCCCCCCCCCCCCCBBCCCBCCCCCCCCCCBCCCCCCCBCCCCBCBCCCBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCBCBCCCBCBCCCCCCCCCCCCCCBCCCCCCCCBCCCCCCCCCCCCCCCCCC...

output:

8086
22 1
21 1
25 9
24 9
25 24
24 24
28 33
27 33
37 38
36 38
44 47
43 47
47 76
46 76
52 85
51 85
60 93
59 93
62 99
61 99
64 108
63 108
81 122
80 122
90 123
89 123
94 131
93 131
122 160
121 160
139 170
138 170
139 183
138 183
153 187
152 187
153 210
152 210
156 212
155 212
166 237
165 237
173 243
172...

result:

ok moves = 8086

Test #21:

score: 0
Accepted
time: 689ms
memory: 6800kb

input:

100002 40466
BBBBBBBCCBCBCCBCBBBBCCBBCBBBBBBBBBBCBBBBCBBBBBCBBBBBBBBBCBBBCBBBCCBCBCBBBBBBCBBBBBBBCBBBBBCBBBBCBCBCBBBBBBBBCBBBBBBBBCBCBBBBCBBBBBBBBBBBBBCBCBBCBBBBBBBBBBBCBBBBBBBCBCBCBCBBBBBBBBCBCBBBBBBBBCBBBBBBBBCBCCBBBCCBBCBBCBBBBBBBBBBCBBBCBBBBBBBBBBBBCBBCCBBCBBCBBBBCBBBBCBBBCCBBBCBBBBBBBCBBBBCBBBC...

output:

45728
9 3
8 3
9 4
8 4
10 22
9 22
11 35
10 35
11 37
10 37
12 42
11 42
16 43
15 43
16 47
15 47
18 62
17 62
28 64
27 64
32 65
31 65
37 74
36 74
46 76
45 76
49 79
48 79
52 84
51 84
52 96
51 96
53 108
52 108
54 109
53 109
60 111
59 111
67 113
66 113
72 128
71 128
76 130
75 130
77 136
76 136
78 139
77 139...

result:

ok moves = 45728

Test #22:

score: -100
Time Limit Exceeded

input:

233338 159967
CCBCBBCCCCBBCCCCCCCCBCCCBCCCCBCCBCCCCCCCCCBCBCCBBCBBCCCCBCCCCCCCCCCCCCCCCCCCBCCBCCBBCBCCBBBCCBCCCCBBCCCBCCCCCCCCCCCBCCBCCCCCCCCBCCCBBCBCCCBCCCCCBCCBCCBCCCCCCCBCCCCCBCCBBCCCCCCCBCCCCCCCCBBBCCCCCCCCCCCCBBBCCCBBCCBCBCCCCCCCCCBCCCCBCCCCCCCCBBCCCCBCCCCBCCCBCCCBCCCCCBCCCCCBBCCCBCCCCCCCCCCCCC...

output:


result: