Submission #58250971


Source Code Expand

#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/io2.hpp"
#define INT(...)   \
  int __VA_ARGS__; \
  IN(__VA_ARGS__)
#define LL(...)   \
  ll __VA_ARGS__; \
  IN(__VA_ARGS__)
#define STR(...)      \
  string __VA_ARGS__; \
  IN(__VA_ARGS__)
#define CHR(...)    \
  char __VA_ARGS__; \
  IN(__VA_ARGS__)
#define DBL(...)           \
  long double __VA_ARGS__; \
  IN(__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 read(int &a) { cin >> a; }
void read(long long &a) { cin >> a; }
void read(char &a) { cin >> a; }
void read(double &a) { cin >> a; }
void read(long double &a) { cin >> a; }
void read(string &a) { cin >> a; }
template <class T, class S>
void read(pair<T, S> &p) {
  read(p.first), read(p.second);
}
template <class T>
void read(vector<T> &a) {
  for (auto &i: a) read(i);
}
template <class T>
void read(T &a) {
  cin >> a;
}
void IN() {}
template <class Head, class... Tail>
void IN(Head &head, Tail &... tail) {
  read(head);
  IN(tail...);
}

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &A) {
  os << A.fi << " " << A.se;
  return os;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<T> &A) {
  for (size_t i = 0; i < A.size(); i++) {
    if (i) os << " ";
    os << A[i];
  }
  return os;
}

// chatgpt helped me
class CoutInitializer {
public:
  CoutInitializer() { std::cout << std::fixed << std::setprecision(15); }
};
static CoutInitializer cout_initializer;

void print() {
  cout << "\n";
  cout.flush();
}

template <class Head, class... Tail>
void print(Head &&head, Tail &&... tail) {
  cout << head;
  if (sizeof...(Tail)) cout << " ";
  print(forward<Tail>(tail)...);
}

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"

const ll N = 150;
const ll K = 25;
vc<string> G0(150);
vc<string> G(150);
ll RND = 423464106810517548;
ll QLE = 0;

// random 15bit
u16 base[150][150];

u64 rnd() {
  static u64 x_ = u64(123856106713094120);
  x_ ^= x_ << 7;
  return x_ ^= x_ >> 9;
}

void init() { FOR(i, N) FOR(j, N) base[i][j] = rnd() & 32767; }

ll dec() {
  ll ANS = 0;
  int dx[] = {1, 0, -1, 0, 1, 0, -1, 0, 1, 0, -1, 0};
  int dy[] = {0, 1, 0, -1, 0, 1, 0, -1, 0, 1, 0, -1};

#ifdef LOCAL
  int gx = 0, gy = 0;
  FOR(i, N) FOR(j, N) {
    if (G[i][j] == 'S') gx = i, gy = j;
  }
  const int sx = gx, sy = gy;
#endif
  FOR(d, 4) {
#ifdef LOCAL
    assert(G[gx][gy] == 'S');
#endif
    int x = 0, y = 0;
    auto step = [&](int k) -> bool {
      ++QLE;
      k = d + k;
      char ch = "DRUL"[k & 3];
#ifdef LOCAL
      int x1 = gx + dx[k], y1 = gy + dy[k];
      if (G[x1][y1] == '.' || G[x1][y1] == 'S') gx = x1, gy = y1;
      return (G[gx][gy] == 'S');
#endif
      print("?", ch);
      char resp;
      read(resp);
      return (resp == 'S');
    };
    vc<string> H(K + 1, string(K + 1, '?'));
    FOR(i, K + 1) FOR(j, K + 1) if (i + j > K) H[i][j] = '#';
    vc<int> X(K + 1), Y(K + 1);
    auto make_road = [&](int a, int b) -> void {
      X[a + b] = a, Y[a + b] = b;
      FOR(i, K + 1) {
        int j = a + b - i;
        if (0 <= j && j < K + 3) H[i][j] = '#';
      }
      H[a][b] = '.';
    };
    make_road(0, 0);
    make_road(1, 0);
    make_road(2, 0);

    FOR(k, 2, K) {
      // move to X[k],Y[k]
      while (x < X[k] || y < Y[k]) {
        if (H[x + 1][y] == '.') {
          ++x;
          assert(!step(0));
        }
        elif (H[x][y + 1] == '.') {
          assert(!step(1));
          ++y;
        }
        else {
          assert(0);
        }
      }
      // 右に行くことを試みる. 右がない, ある
      pair<int, int> XY0, XY1;
      XY0 = {X[k], Y[k]}, XY1 = {X[k] + 1, Y[k]};
      step(0);
      auto nxt = [&](int d, pair<int, int> p) -> pair<int, int> {
        auto [x, y] = p;
        int x1 = x + dx[d], y1 = y + dy[d];
        if (0 <= x1 && 0 <= y1 && H[x1][y1] == '.') return {x1, y1};
        return {x, y};
      };
      while (1) {
        auto [a, b] = XY0;
        int d = (a > 0 && H[a - 1][b] == '.' ? 2 : 3);
        XY0 = nxt(d, XY0);
        XY1 = nxt(d, XY1);
        bool end = step(d);
        if (end) {
          assert(XY0 == mp(0, 0));
          // 右に行かなかった
          x = 0, y = 0;
          make_road(X[k], Y[k] + 1);
          break;
        }
        if (XY0 != mp(0, 0)) continue;
        make_road(X[k] + 1, Y[k]);
        tie(x, y) = XY1;
        break;
      }
    }
    // 中央に戻る
    while (x > 0 || y > 0) {
      int d = (x > 0 && H[x - 1][y] == '.' ? 2 : 3);
      step(d);
      x += dx[d], y += dy[d];
    }
    ll ans = 0;
    FOR(i, K + 1) FOR(j, K + 1) if (H[i][j] == '.') ans ^= base[i][j];
    ANS |= ans << (15 * d);
  }
  return ANS ^ RND;
}

using BS = bitset<32768>;
BS dp[K + 1][K + 1];

bool try_enc(ll X) {
  int dx[] = {1, 0, -1, 0, 1, 0, -1, 0, 1, 0, -1, 0};
  int dy[] = {0, 1, 0, -1, 0, 1, 0, -1, 0, 1, 0, -1};
  FOR(i, N) G[i] = G0[i];

  auto [cx, cy] = [&]() -> pair<int, int> {
    while (1) {
      int x = rnd() % 70 + 40;
      int y = rnd() % 70 + 40;
      if (G[x][y] == '#') continue;
      if (G[x + 1][y] == '#') continue;
      if (G[x + 2][y] == '#') continue;
      if (G[x][y + 1] == '#') continue;
      if (G[x][y + 2] == '#') continue;
      if (G[x - 1][y] == '#') continue;
      if (G[x - 2][y] == '#') continue;
      if (G[x][y - 1] == '#') continue;
      if (G[x][y - 2] == '#') continue;
      return {x, y};
    }
    assert(0);
  }();
  FOR(x, N) FOR(y, N) if (G[x][y] == '.') G[x][y] = '?';

  FOR(d, 4) {
    ll Y = (X ^ RND) >> (15 * d) & 32767;
    FOR(i, K + 1) FOR(j, K - i + 1) dp[i][j].reset();
    dp[0][0][base[0][0]] = 1;

    auto get = [&](int i, int j) -> pair<int, int> {
      int x = cx + i * dx[d] + j * dx[d + 1];
      int y = cy + i * dy[d] + j * dy[d + 1];
      return {x, y};
    };

    FOR(i, K + 1) FOR(j, K - i + 1) {
      auto [x, y] = get(i, j);
      if (G[x][y] == '#') continue;
      if (i + 1 < K) {
        auto [x1, y1] = get(i + 1, j);
        if (G[x1][y1] != '#') { FOR(k, 32768) if (dp[i][j][k]) dp[i + 1][j][k ^ base[i + 1][j]] = 1; }
      }
      if (i >= 2 && j + 1 < K) {
        auto [x1, y1] = get(i, j + 1);
        if (G[x1][y1] != '#') { FOR(k, 32768) if (dp[i][j][k]) dp[i][j + 1][k ^ base[i][j + 1]] = 1; }
      }
    }
    int a = infty<int>, b = infty<int>;
    FOR(i, K + 1) {
      if (dp[i][K - i][Y]) a = i, b = K - i;
    }
    if (a == infty<int>) return 0;
    while (1) {
      auto [x, y] = get(a, b);
      G[x][y] = '.';
      Y ^= base[a][b];
      if (a == 0 && b == 0) {
        assert(Y == 0);
        break;
      }
      if (a > 0 && dp[a - 1][b][Y]) { a -= 1; }
      elif (b > 0 && dp[a][b - 1][Y]) { b -= 1; }
      else {
        assert(0);
      }
    }
  }
  G[cx][cy] = 'S';
  FOR(x, N) FOR(y, N) if (G[x][y] == '?') G[x][y] = '#';
  FOR(d, 4) G[cx + dx[d]][cy + dy[d]] = '.';
  FOR(x, N) print(G[x]);
  return 1;
}

void solve() {
  STR(S);
  if (S == "encode") {
    LL(X);
    FOR(i, N) read(G0[i]);
    while (!try_enc(X)) {}
    return;
  }
  elif (S == "decode") {
#ifdef LOCAL
    FOR(i, N) read(G[i]);
#endif
    ll ANS = dec();
    assert(QLE <= 2300);
#ifdef LOCAL
    print("ANS=", ANS, "QLE=", QLE);
#endif
    return print("!", ANS);
  }
}

signed main() {
  init();
  solve();
  return 0;
}

Submission Info

Submission Time
Task I - encode/decode 2019
User maspy
Language C++ 20 (gcc 12.2)
Score 400
Code Size 14650 Byte
Status AC
Exec Time 343 ms
Memory 5384 KiB

Judge Result

Set Name All
Score / Max Score 400 / 400
Status
AC × 25
Set Name Test Cases
All random_00, random_01, random_02, random_03, random_04, random_05, random_06, random_07, random_08, random_09, random_10, random_11, random_12, random_13, random_14, random_15, random_16, random_17, random_18, random_19, random_20, random_21, random_22, random_23, random_24
Case Name Status Exec Time Memory
random_00 AC 117 ms 5200 KiB
random_01 AC 92 ms 5252 KiB
random_02 AC 106 ms 5260 KiB
random_03 AC 227 ms 5192 KiB
random_04 AC 193 ms 5200 KiB
random_05 AC 146 ms 5256 KiB
random_06 AC 148 ms 5196 KiB
random_07 AC 299 ms 5204 KiB
random_08 AC 100 ms 5248 KiB
random_09 AC 317 ms 5260 KiB
random_10 AC 297 ms 5260 KiB
random_11 AC 110 ms 5192 KiB
random_12 AC 147 ms 5188 KiB
random_13 AC 51 ms 5228 KiB
random_14 AC 96 ms 5256 KiB
random_15 AC 236 ms 5328 KiB
random_16 AC 84 ms 5156 KiB
random_17 AC 329 ms 5324 KiB
random_18 AC 187 ms 5240 KiB
random_19 AC 172 ms 5268 KiB
random_20 AC 174 ms 5128 KiB
random_21 AC 50 ms 5384 KiB
random_22 AC 254 ms 5332 KiB
random_23 AC 299 ms 5268 KiB
random_24 AC 343 ms 5240 KiB