QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#107588#5664. Printing StickersmaspyAC ✓18831ms7512kbC++2324.9kb2023-05-22 04:21:472023-05-22 04:21:49

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-05-22 04:21:49]
  • 评测
  • 测评结果:AC
  • 用时:18831ms
  • 内存:7512kb
  • [2023-05-22 04:21:47]
  • 提交

answer

#line 1 "library/my_template.hpp"
#if defined(LOCAL)
#include <my_template_compiled.hpp>
#else
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using u32 = unsigned int;
using u64 = unsigned long long;
using i128 = __int128;

template <class T>
constexpr T infty = 0;
template <>
constexpr int infty<int> = 1'000'000'000;
template <>
constexpr ll infty<ll> = ll(infty<int>) * infty<int> * 2;
template <>
constexpr u32 infty<u32> = infty<int>;
template <>
constexpr u64 infty<u64> = infty<ll>;
template <>
constexpr i128 infty<i128> = i128(infty<ll>) * infty<ll>;
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); }
// (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, typename U>
T ceil(T x, U y) {
  return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U>
T floor(T x, U y) {
  return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T, typename U>
pair<T, T> divmod(T x, U y) {
  T q = floor(x, y);
  return {q, x - q * y};
}

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

#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) {
  assert(!que.empty());
  T a = que.top();
  que.pop();
  return a;
}
template <typename T>
T POP(vc<T> &que) {
  assert(!que.empty());
  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;
    tie(ok, ng) = (check(x) ? mp(x, ng) : mp(ok, 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;
    tie(ok, ng) = (check(x) ? mp(x, ng) : mp(ok, 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;
}
#endif
#line 1 "library/other/io.hpp"
// based on yosupo's fastio
#include <unistd.h>

namespace fastio {
#define FASTIO
// クラスが read(), print() を持っているかを判定するメタ関数
struct has_write_impl {
  template <class T>
  static auto check(T &&x) -> decltype(x.write(), std::true_type{});

  template <class T>
  static auto check(...) -> std::false_type;
};

template <class T>
class has_write : public decltype(has_write_impl::check<T>(std::declval<T>())) {
};

struct has_read_impl {
  template <class T>
  static auto check(T &&x) -> decltype(x.read(), std::true_type{});

  template <class T>
  static auto check(...) -> std::false_type;
};

template <class T>
class has_read : public decltype(has_read_impl::check<T>(std::declval<T>())) {};

struct Scanner {
  FILE *fp;
  char line[(1 << 15) + 1];
  size_t st = 0, ed = 0;
  void reread() {
    memmove(line, line + st, ed - st);
    ed -= st;
    st = 0;
    ed += fread(line + ed, 1, (1 << 15) - ed, fp);
    line[ed] = '\0';
  }
  bool succ() {
    while (true) {
      if (st == ed) {
        reread();
        if (st == ed) return false;
      }
      while (st != ed && isspace(line[st])) st++;
      if (st != ed) break;
    }
    if (ed - st <= 50) {
      bool sep = false;
      for (size_t i = st; i < ed; i++) {
        if (isspace(line[i])) {
          sep = true;
          break;
        }
      }
      if (!sep) reread();
    }
    return true;
  }
  template <class T, enable_if_t<is_same<T, string>::value, int> = 0>
  bool read_single(T &ref) {
    if (!succ()) return false;
    while (true) {
      size_t sz = 0;
      while (st + sz < ed && !isspace(line[st + sz])) sz++;
      ref.append(line + st, sz);
      st += sz;
      if (!sz || st != ed) break;
      reread();
    }
    return true;
  }
  template <class T, enable_if_t<is_integral<T>::value, int> = 0>
  bool read_single(T &ref) {
    if (!succ()) return false;
    bool neg = false;
    if (line[st] == '-') {
      neg = true;
      st++;
    }
    ref = T(0);
    while (isdigit(line[st])) { ref = 10 * ref + (line[st++] & 0xf); }
    if (neg) ref = -ref;
    return true;
  }
  template <typename T,
            typename enable_if<has_read<T>::value>::type * = nullptr>
  inline bool read_single(T &x) {
    x.read();
    return true;
  }
  bool read_single(double &ref) {
    string s;
    if (!read_single(s)) return false;
    ref = std::stod(s);
    return true;
  }
  bool read_single(char &ref) {
    string s;
    if (!read_single(s) || s.size() != 1) return false;
    ref = s[0];
    return true;
  }
  template <class T>
  bool read_single(vector<T> &ref) {
    for (auto &d: ref) {
      if (!read_single(d)) return false;
    }
    return true;
  }
  template <class T, class U>
  bool read_single(pair<T, U> &p) {
    return (read_single(p.first) && read_single(p.second));
  }
  template <size_t N = 0, typename T>
  void read_single_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
      auto &x = std::get<N>(t);
      read_single(x);
      read_single_tuple<N + 1>(t);
    }
  }
  template <class... T>
  bool read_single(tuple<T...> &tpl) {
    read_single_tuple(tpl);
    return true;
  }
  void read() {}
  template <class H, class... T>
  void read(H &h, T &... t) {
    bool f = read_single(h);
    assert(f);
    read(t...);
  }
  Scanner(FILE *fp) : fp(fp) {}
};

struct Printer {
  Printer(FILE *_fp) : fp(_fp) {}
  ~Printer() { flush(); }

  static constexpr size_t SIZE = 1 << 15;
  FILE *fp;
  char line[SIZE], small[50];
  size_t pos = 0;
  void flush() {
    fwrite(line, 1, pos, fp);
    pos = 0;
  }
  void write(const char val) {
    if (pos == SIZE) flush();
    line[pos++] = val;
  }
  template <class T, enable_if_t<is_integral<T>::value, int> = 0>
  void write(T val) {
    if (pos > (1 << 15) - 50) flush();
    if (val == 0) {
      write('0');
      return;
    }
    if (val < 0) {
      write('-');
      val = -val; // todo min
    }
    size_t len = 0;
    while (val) {
      small[len++] = char(0x30 | (val % 10));
      val /= 10;
    }
    for (size_t i = 0; i < len; i++) { line[pos + i] = small[len - 1 - i]; }
    pos += len;
  }
  void write(const string s) {
    for (char c: s) write(c);
  }
  void write(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++) write(s[i]);
  }
  void write(const double x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << x;
    string s = oss.str();
    write(s);
  }
  void write(const long double x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << x;
    string s = oss.str();
    write(s);
  }
  template <typename T,
            typename enable_if<has_write<T>::value>::type * = nullptr>
  inline void write(T x) {
    x.write();
  }
  template <class T>
  void write(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
      if (i) write(' ');
      write(val[i]);
    }
  }
  template <class T, class U>
  void write(const pair<T, U> val) {
    write(val.first);
    write(' ');
    write(val.second);
  }
  template <size_t N = 0, typename T>
  void write_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
      if constexpr (N > 0) { write(' '); }
      const auto x = std::get<N>(t);
      write(x);
      write_tuple<N + 1>(t);
    }
  }
  template <class... T>
  bool write(tuple<T...> tpl) {
    write_tuple(tpl);
    return true;
  }
  template <class T, size_t S>
  void write(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
      if (i) write(' ');
      write(val[i]);
    }
  }
  void write(i128 val) {
    string s;
    bool negative = 0;
    if (val < 0) {
      negative = 1;
      val = -val;
    }
    while (val) {
      s += '0' + int(val % 10);
      val /= 10;
    }
    if (negative) s += "-";
    reverse(all(s));
    if (len(s) == 0) s = "0";
    write(s);
  }
};
Scanner scanner = Scanner(stdin);
Printer printer = Printer(stdout);
void flush() { printer.flush(); }
void print() { printer.write('\n'); }
template <class Head, class... Tail>
void print(Head &&head, Tail &&... tail) {
  printer.write(head);
  if (sizeof...(Tail)) printer.write(' ');
  print(forward<Tail>(tail)...);
}

void read() {}
template <class Head, class... Tail>
void read(Head &head, Tail &... tail) {
  scanner.read(head);
  read(tail...);
}
} // namespace fastio
using fastio::print;
using fastio::flush;
using fastio::read;

#define INT(...)   \
  int __VA_ARGS__; \
  read(__VA_ARGS__)
#define LL(...)   \
  ll __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 "library/ds/unionfind/unionfind.hpp"

struct UnionFind {
  int n, n_comp;
  vc<int> dat; // par or (-size)
  UnionFind(int n = 0) { build(n); }

  void build(int m) {
    n = m, n_comp = m;
    dat.assign(n, -1);
  }

  void reset() { build(n); }

  int operator[](int x) {
    while (dat[x] >= 0) {
      int pp = dat[dat[x]];
      if (pp < 0) { return dat[x]; }
      x = dat[x] = pp;
    }
    return x;
  }

  ll size(int x) {
    assert(dat[x] < 0);
    return -dat[x];
  }

  bool merge(int x, int y) {
    x = (*this)[x], y = (*this)[y];
    if (x == y) return false;
    if (-dat[x] < -dat[y]) swap(x, y);
    dat[x] += dat[y], dat[y] = x, n_comp--;
    return true;
  }
};
#line 2 "library/graph/base.hpp"

template <typename T>
struct Edge {
  int frm, to;
  T cost;
  int id;
};

template <typename T = int, bool directed = false>
struct Graph {
  int N, M;
  using cost_type = T;
  using edge_type = Edge<T>;
  vector<edge_type> edges;
  vector<int> indptr;
  vector<edge_type> csr_edges;
  vc<int> vc_deg, vc_indeg, vc_outdeg;
  bool prepared;

  class OutgoingEdges {
  public:
    OutgoingEdges(const Graph* G, int l, int r) : G(G), l(l), r(r) {}

    const edge_type* begin() const {
      if (l == r) { return 0; }
      return &G->csr_edges[l];
    }

    const edge_type* end() const {
      if (l == r) { return 0; }
      return &G->csr_edges[r];
    }

  private:
    const Graph* G;
    int l, r;
  };

  bool is_prepared() { return prepared; }
  constexpr bool is_directed() { return directed; }

  Graph() : N(0), M(0), prepared(0) {}
  Graph(int N) : N(N), M(0), prepared(0) {}

  void build(int n) {
    N = n, M = 0;
    prepared = 0;
    edges.clear();
    indptr.clear();
    csr_edges.clear();
    vc_deg.clear();
    vc_indeg.clear();
    vc_outdeg.clear();
  }

  void add(int frm, int to, T cost = 1, int i = -1) {
    assert(!prepared);
    assert(0 <= frm && 0 <= to && to < N);
    if (i == -1) i = M;
    auto e = edge_type({frm, to, cost, i});
    edges.eb(e);
    ++M;
  }

  // wt, off
  void read_tree(bool wt = false, int off = 1) { read_graph(N - 1, wt, off); }

  void read_graph(int M, bool wt = false, int off = 1) {
    for (int m = 0; m < M; ++m) {
      INT(a, b);
      a -= off, b -= off;
      if (!wt) {
        add(a, b);
      } else {
        T c;
        read(c);
        add(a, b, c);
      }
    }
    build();
  }

  void build() {
    assert(!prepared);
    prepared = true;
    indptr.assign(N + 1, 0);
    for (auto&& e: edges) {
      indptr[e.frm + 1]++;
      if (!directed) indptr[e.to + 1]++;
    }
    for (int v = 0; v < N; ++v) { indptr[v + 1] += indptr[v]; }
    auto counter = indptr;
    csr_edges.resize(indptr.back() + 1);
    for (auto&& e: edges) {
      csr_edges[counter[e.frm]++] = e;
      if (!directed)
        csr_edges[counter[e.to]++] = edge_type({e.to, e.frm, e.cost, e.id});
    }
  }

  OutgoingEdges operator[](int v) const {
    assert(prepared);
    return {this, indptr[v], indptr[v + 1]};
  }

  vc<int> deg_array() {
    if (vc_deg.empty()) calc_deg();
    return vc_deg;
  }

  pair<vc<int>, vc<int>> deg_array_inout() {
    if (vc_indeg.empty()) calc_deg_inout();
    return {vc_indeg, vc_outdeg};
  }

  int deg(int v) {
    if (vc_deg.empty()) calc_deg();
    return vc_deg[v];
  }

  int in_deg(int v) {
    if (vc_indeg.empty()) calc_deg_inout();
    return vc_indeg[v];
  }

  int out_deg(int v) {
    if (vc_outdeg.empty()) calc_deg_inout();
    return vc_outdeg[v];
  }

  void debug() {
    print("Graph");
    if (!prepared) {
      print("frm to cost id");
      for (auto&& e: edges) print(e.frm, e.to, e.cost, e.id);
    } else {
      print("indptr", indptr);
      print("frm to cost id");
      FOR(v, N) for (auto&& e: (*this)[v]) print(e.frm, e.to, e.cost, e.id);
    }
  }

  vc<int> new_idx;
  vc<bool> used_e;

  // G における頂点 V[i] が、新しいグラフで i になるようにする
  // {G, es}
  pair<Graph<T, directed>, vc<int>> rearrange(vc<int> V) {
    if (len(new_idx) != N) new_idx.assign(N, -1);
    if (len(used_e) != M) used_e.assign(M, 0);
    int n = len(V);
    FOR(i, n) new_idx[V[i]] = i;
    Graph<T, directed> G(n);
    vc<int> es;
    FOR(i, n) {
      for (auto&& e: (*this)[V[i]]) {
        if (used_e[e.id]) continue;
        int a = e.frm, b = e.to;
        if (new_idx[a] != -1 && new_idx[b] != -1) {
          used_e[e.id] = 1;
          G.add(new_idx[a], new_idx[b], e.cost);
          es.eb(e.id);
        }
      }
    }
    FOR(i, n) new_idx[V[i]] = -1;
    for (auto&& eid: es) used_e[eid] = 0;
    G.build();
    return {G, es};
  }

private:
  void calc_deg() {
    assert(vc_deg.empty());
    vc_deg.resize(N);
    for (auto&& e: edges) vc_deg[e.frm]++, vc_deg[e.to]++;
  }

  void calc_deg_inout() {
    assert(vc_indeg.empty());
    vc_indeg.resize(N);
    vc_outdeg.resize(N);
    for (auto&& e: edges) { vc_indeg[e.to]++, vc_outdeg[e.frm]++; }
  }
};
#line 1 "library/flow/maxflow.hpp"
template <typename Cap>
struct MaxFlowGraph {
  struct Edge {
    int to, rev;
    Cap cap;
  };

  int N;
  vc<tuple<int, int, Cap, Cap>> dat;
  vc<int> prog, level;
  vc<int> que;
  vc<Edge> G;
  vc<int> indptr;
  Cap flow_ans;
  bool calculated;
  bool is_prepared;

  MaxFlowGraph(int N) : N(N), calculated(0), is_prepared(0) {}

  void add(int frm, int to, Cap cap, Cap rev_cap = 0) {
    assert(0 <= frm && frm < N);
    assert(0 <= to && to < N);
    assert(Cap(0) <= cap);
    if (frm == to) return;
    dat.eb(frm, to, cap, rev_cap);
  }

  void build() {
    assert(!is_prepared);
    int M = len(dat);
    is_prepared = 1;
    indptr.assign(N, 0);
    for (auto&& [a, b, c, d]: dat) indptr[a]++, indptr[b]++;
    indptr = cumsum<int>(indptr);
    vc<int> nxt_idx = indptr;
    G.resize(2 * M);
    for (auto&& [a, b, c, d]: dat) {
      int p = nxt_idx[a]++;
      int q = nxt_idx[b]++;
      G[p] = Edge{b, q, c};
      G[q] = Edge{a, p, d};
    }
  }

  Cap flow(int source, int sink) {
    assert(is_prepared);
    if (calculated) return flow_ans;
    calculated = true;
    flow_ans = 0;
    while (set_level(source, sink)) {
      prog = indptr;
      while (1) {
        Cap x = flow_dfs(source, sink, infty<Cap>);
        if (x == 0) break;
        flow_ans += x;
        chmin(flow_ans, infty<Cap>);
        if (flow_ans == infty<Cap>) return flow_ans;
      }
    }
    return flow_ans;
  }

  // 最小カットの値および、カットを表す 01 列を返す
  pair<Cap, vc<int>> cut(int source, int sink) {
    Cap f = flow(source, sink);
    vc<int> res(N);
    FOR(v, N) res[v] = (level[v] >= 0 ? 0 : 1);
    return {f, res};
  }

  // 残余グラフの辺
  vc<tuple<int, int, Cap>> get_edges() {
    vc<tuple<int, int, Cap>> edges;
    FOR(v, N) {
      FOR(k, indptr[v], indptr[v + 1]) {
        auto& e = G[k];
        edges.eb(v, e.to, e.cap);
      }
    }
    return edges;
  }

private:
  bool set_level(int source, int sink) {
    que.resize(N);
    level.assign(N, -1);
    level[source] = 0;
    int l = 0, r = 0;
    que[r++] = source;
    while (l < r) {
      int v = que[l++];
      FOR(k, indptr[v], indptr[v + 1]) {
        auto& e = G[k];
        if (e.cap > 0 && level[e.to] == -1) {
          level[e.to] = level[v] + 1;
          if (e.to == sink) return true;
          que[r++] = e.to;
        }
      }
    }
    return false;
  }

  Cap flow_dfs(int v, int sink, Cap lim) {
    if (v == sink) return lim;
    Cap res = 0;
    for (int& i = prog[v]; i < indptr[v + 1]; ++i) {
      auto& e = G[i];
      if (e.cap > 0 && level[e.to] == level[v] + 1) {
        Cap a = flow_dfs(e.to, sink, min(lim, e.cap));
        if (a > 0) {
          e.cap -= a;
          G[e.rev].cap += a;
          res += a;
          lim -= a;
          if (lim == 0) break;
        }
      }
    }
    return res;
  }
};
#line 7 "main.cpp"

void solve() {
  LL(H, W, X, Y);

  auto idx = [&](int x, int y, int side) -> int {
    return (W + W) * x + (2 * y + side);
  };

  VEC(string, shape, H);
  VEC(string, color, H);
  VV(int, cost, H, W);

  using P = pair<int, int>;
  using T = array<P, 3>;
  vvv(T, dat, H, W, 2);

  // 三角形の座標
  FOR(x, H) FOR(y, W) FOR(s, 2) {
    if (s == 0) {
      dat[x][y][s][0] = {x, y};
      dat[x][y][s][1] = {x + 1, y};
      if (shape[x][y] == '/') {
        dat[x][y][s][2] = {x, y + 1};
      } else {
        dat[x][y][s][2] = {x + 1, y + 1};
      }
    }
    if (s == 1) {
      dat[x][y][s][0] = {x, y + 1};
      dat[x][y][s][1] = {x + 1, y + 1};
      if (shape[x][y] == '/') {
        dat[x][y][s][2] = {x + 1, y};
      } else {
        dat[x][y][s][2] = {x, y};
      }
    };
  }

  UnionFind uf(2 * H * W + 1);
  auto merge = [&](int x1, int y1, int s1, int x2, int y2, int s2) -> void {
    if (color[x1][2 * y1 + s1] != '#') return;
    if (color[x2][2 * y2 + s2] != '#') return;
    uf.merge(idx(x1, y1, s1), idx(x2, y2, s2));
  };

  // merge black cells
  FOR(x1, H) FOR(y1, W) {
    // share vertex
    FOR(dx, -1, 2) FOR(dy, -1, 2) {
      int x2 = x1 + dx, y2 = y1 + dy;
      if (x2 < 0 || x2 >= H) continue;
      if (y2 < 0 || y2 >= W) continue;
      FOR(s1, 2) FOR(s2, 2) {
        T A = dat[x1][y1][s1];
        T B = dat[x2][y2][s2];
        bool ok = 0;
        FOR(i, 3) FOR(j, 3) if (A[i] == B[j]) ok = 1;
        if (ok) merge(x1, y1, s1, x2, y2, s2);
      }
    }
  }

  vc<int> roots;
  FOR(x, H) FOR(y, W) FOR(s, 2) {
    int i = idx(x, y, s);
    if (uf[i] != i) continue;
    if (color[x][2 * y + s] != '#') continue;
    roots.eb(i);
  }

  vc<tuple<int, int, int>> edge;
  auto add = [&](int a, int b, int c) -> void { edge.eb(uf[a], uf[b], c); };

  int sink = 2 * H * W;
  // diagonal
  FOR(x, H) FOR(y, W) {
    int c = cost[x][y];
    if (color[x][2 * y + 0] == '#' || color[x][2 * y + 1] == '#') {
      c = infty<int>;
    }
    add(idx(x, y, 0), idx(x, y, 1), c);
    // add(idx(x, y, 1), idx(x, y, 0), c);
  }
  // x,x+1
  FOR(x, -1, H) FOR(y, W) {
    int c = X;
    int a = sink;
    if (x >= 0) {
      int s = (shape[x][y] == '/' ? 1 : 0);
      if (color[x][2 * y + s] == '#') { c = infty<int>; }
      a = idx(x, y, s);
    }
    int b = sink;
    if (x + 1 < H) {
      int s = (shape[x + 1][y] == '/' ? 0 : 1);
      if (color[x + 1][2 * y + s] == '#') { c = infty<int>; }
      b = idx(x + 1, y, s);
    }
    add(a, b, c);
    // add(b, a, c);
  }
  // y,y+1
  FOR(x, H) FOR(y, -1, W) {
    int c = Y;
    int a = sink;
    if (y >= 0) {
      int s = (shape[x][y] == '/' ? 1 : 1);
      if (color[x][2 * y + s] == '#') { c = infty<int>; }
      a = idx(x, y, s);
    }
    int b = sink;
    if (y + 1 < W) {
      int s = (shape[x][y + 1] == '/' ? 0 : 0);
      if (color[x][2 * (y + 1) + s] == '#') { c = infty<int>; }
      b = idx(x, y + 1, s);
    }
    add(a, b, c);
    // add(b, a, c);
  }

  vi ANS;
  for (auto&& root: roots) {
    MaxFlowGraph<int> G(2 * H * W + 1);
    for (auto&& t: roots) {
      if (root != t) G.add(t, sink, infty<int>, 0);
    }
    for (auto&& [a, b, c]: edge) G.add(a, b, c, c);
    G.build();
    int ans = G.flow(root, sink);
    // print(ans);
    ANS.eb(ans);
  }

  sort(all(ANS));
  print(len(ANS));
  print(ANS);
}

signed main() {
  INT(T);
  FOR(T) solve();
  return 0;
}

详细

Test #1:

score: 100
Accepted
time: 2ms
memory: 3392kb

input:

1
4 9 10 10
\////\\/\
\\/\//\//
//\\/\\/\
\///\//\/
.....#...##.......
.##.#.....##...##.
...#.##....####...
..#.........#..##.
1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1

output:

2
86 106

result:

ok 2 lines

Test #2:

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

input:

1
8 12 20 19
\//\//\/\\\/
//\/\\\/////
///\/\\\\//\
\//\\\/\/\/\
\\\\\///\///
///\\\\\\\\\
//\/////\\\\
/////\//////
........................
..##################....
..##..............##....
..##..######....##......
..##..##......####..##..
..##........##......##..
..############....####..
...........

output:

3
196 214 723

result:

ok 2 lines

Test #3:

score: 0
Accepted
time: 2ms
memory: 3488kb

input:

4
4 9 10 10
\////\\/\
\\/\//\//
//\\/\\/\
\///\//\/
.....#...##.......
.##.#.....##...##.
...#.##....####...
..#.........#..##.
1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1
8 12 20 19
\//\//\/\\\/
//\/\\\/////
///\/\\\\//\
\//\\\/\/\/\
\\\\\///\///
///\\\\\\\\\
//\/////\\\...

output:

2
86 106
3
196 214 723
3
104 159 537
1
42

result:

ok 8 lines

Test #4:

score: 0
Accepted
time: 8629ms
memory: 6820kb

input:

50
49 204 993 979
///\/\/\\\///\\//////\/\\\/\\\\//\\/\\\////\/\/\\\/\/\/\/\\/\/\/\///\/\\\//\///\/\\\\\/\//\\\\\\\\//\//\\\\\\//\///\///\\//\\/\/\\/\\/\\//\\\\\\/\\\//\/\////\\\\//\\////\\\/\///\/\//\\\//\///\\\/\\/\\\//\
\\//\\/\\///\//\\\\/\/\\\\\//\\/\/\////\\//\//\//\////\//\/\/\/\\\//\\////\//...

output:

26
4745 4847 5354 5486 5487 5697 5702 5715 5731 5739 5744 5784 5839 6654 7455 7677 7733 8463 9218 9578 10530 11334 12254 13358 16125 645597
583
4435 4444 4495 4497 4528 4537 4551 4563 4573 4577 4585 4603 4611 4643 4663 4686 4699 4711 4715 4745 4778 4851 5337 5362 5365 5389 5406 5416 5430 5436 5439 5...

result:

ok 100 lines

Test #5:

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

input:

50
6 3 993 979
///
\/\
/\\
\//
/\\
///
...#..
......
..#...
...##.
......
......
839 804 858
813 939 867
937 833 938
971 960 829
951 856 906
888 997 891
2 7 816 957
/\/\///
\/\\\//
.##..#...#....
.........#..#.
860 948 909 960 975 918 901
976 995 835 880 906 891 825
3 6 975 956
\\//\/
//\///
\\//\\
...

output:

2
5435 7646
3
5338 6210 8746
1
5275
2
5500 8373
3
5195 5202 7619
1
13672
1
9553
1
4517
2
5545 5626
2
5476 9891
1
15834
3
5381 5435 6302
1
5250
3
6282 6996 7945
3
6490 7661 9784
4
5594 5762 5810 5886
2
5675 14393
1
16122
4
5371 5391 5392 6195
4
5560 5627 7485 8423
2
5717 11501
3
4638 6238 9961
3
5350...

result:

ok 100 lines

Test #6:

score: 0
Accepted
time: 39ms
memory: 3656kb

input:

50
11 36 993 979
///\/\/\\\///\\//////\/\\\/\\\\//\\/
\\\////\/\/\\\/\/\/\/\\/\/\/\///\/\\
\//\///\/\\\\\/\//\\\\\\\\//\//\\\\\
\//\///\///\\//\\/\/\\/\\/\\//\\\\\\
/\\\//\/\////\\\\//\\////\\\/\///\/\
//\\\//\///\\\/\\/\\\//\\\//\\/\\///
\//\\\\/\/\\\\\//\\/\/\////\\//\//\/
/\////\//\/\/\/\\\//\\//...

output:

7
3968 3971 3973 3973 7914 9902 71559
5
1743 3448 3495 5323 53385
4
2013 11937 13816 55153
29
1663 1665 1682 1684 1688 1690 1699 1699 1745 1788 1863 3285 3311 3339 3345 3349 3384 3389 3440 3564 5026 5178 5216 6645 6672 6864 8470 11692 18685
17
1815 3447 5274 5367 6818 6912 7104 7143 8667 8866 8877 1...

result:

ok 100 lines

Test #7:

score: 0
Accepted
time: 10630ms
memory: 7156kb

input:

50
188 53 914 991
//\//////////////////////////////////////////////////
///////////////////\/////////////////\///////////////
/////////////////////////////////////////////////////
/////////\//////////////\////////////////////////////
/////////////////////////////////////////////////////
////////////...

output:

601
374 2004 2014 2017 2100 2102 2123 2133 2174 2183 2186 2192 2214 2271 2378 2450 2458 2483 2611 2723 3821 3821 3822 3823 3823 3825 3825 3825 3826 3826 3826 3826 3827 3827 3827 3827 3828 3828 3828 3828 3828 3829 3830 3830 3830 3830 3830 3830 3830 3830 3830 3831 3831 3831 3832 3832 3832 3832 3833 38...

result:

ok 100 lines

Test #8:

score: 0
Accepted
time: 382ms
memory: 6108kb

input:

50
41 243 995 824
/\///\\/\\\\///\/\/\////\//\////\/\/\/\\/\//\\/\/\//\//\////\\//\/\//\///\//\\//\\\//////\/\/\//\//\/\//\\/////\/\\//////\/\\///\\\/\\\///\\\/\//\//\//\\//\\\\\\\////\/\/\///\///\/\/\\\\/\/\///\///////\//\\//\\\/\///\\///\\/\/\//\//////\\/\\//
/\\\\\\\/\/////\//////\//\////\///\//\...

output:

1
526921
8
1967 3788 3795 3801 3827 3850 3883 338854
1
587397
1
373763
1
431602
1
366690
3
3480 3576 2212988
3
4017 4019 342820
3
1878 3556 645568
10
2080 3835 3838 3844 3846 3849 3959 5768 7600 384179
1
367560
1
351648
1
335366
1
337884
1
399771
2
3873 335759
19
1808 3435 3520 3548 3549 3554 3556 3...

result:

ok 100 lines

Test #9:

score: 0
Accepted
time: 2391ms
memory: 7440kb

input:

50
277 36 902 865
\/////\/\\\////\\/\\\\\/\\\\\\\\\/\\
/\\\\\\\\\/\\\\///\\\\/\\//\/\\//\//
\\\/\\\\////\\\//\\\\\/\\\\\\///\/\\
\\/\/\\\//\\\/\\\//\\//\\\/\\/\\\\\/
\/\\//\\\\\\\/\/\\\//\//\/\/\//\/\/\
//\\/\\/\\\\\\\\\/\\/\/\//\\\\\\\/\\
/\\\\\\\\\/\/\/\\\\\\\\/\\\///\/\\\/
///\\/\////\\\\\//\\\\\...

output:

9
1895 3620 3628 3630 3707 3717 5352 7165 505237
71
271 2015 2019 2027 2086 2093 2098 2101 2110 2110 2113 2118 2176 2184 2205 2274 2277 2291 2295 2381 2390 3849 3852 3852 3852 3853 3854 3857 3858 3864 3865 3933 3938 3939 3940 3941 3945 3947 3948 3951 3958 3960 3961 4013 4023 4032 4049 4065 4071 5693...

result:

ok 100 lines

Test #10:

score: 0
Accepted
time: 2361ms
memory: 6416kb

input:

50
23 434 9 9
////\////////\/\/////\//\///\/////////\/\////\/\////\\/\///////\///\//////\////////\////\/\/////\/\\/\/\//\/////////////\////\///\////\\/\////\/\///////////\\/////\//////\/\\//\\///////////\//\//////\/\//////////////////\\//////\/\//////////////\/////////\///////\///\\/\\/\/////////\\/...

output:

53
72 72 72 72 72 72 72 72 72 72 72 72 72 72 72 72 72 72 72 90 90 90 90 108 108 955 960 972 982 999 999 1016 1019 1023 1025 1026 1041 1048 1053 1062 1065 1068 1071 1071 1071 1071 1986 1995 2000 2034 9408 9537 28511
74
60 60 60 60 60 60 60 60 60 60 60 60 72 72 72 72 72 72 72 72 84 84 84 90 90 90 90 9...

result:

ok 100 lines

Test #11:

score: 0
Accepted
time: 18831ms
memory: 7512kb

input:

50
49 204 10 990
///\//////\/////\//\///////////////////\/\////////////////\/////\/\/////\////\///////\/\/////////////////////////\/\////////////////\//////////////\/////\//////\//////////////\/\/\/////\//////////////\\//
//////////\/////////////////////////////////\/\\//\///\/////////////////\/////...

output:

291
2094 2099 2100 2102 2102 2105 2108 2110 2111 2111 2114 2114 2116 2116 2116 2120 2121 2123 2123 2125 2125 2126 2130 2131 2131 2131 2132 2134 2134 2134 2135 2135 2138 2138 2139 2139 2140 2140 2141 2141 2141 2141 2143 2143 2143 2144 2145 2147 2147 2148 2148 2148 2148 2150 2150 2150 2151 2151 2152 2...

result:

ok 100 lines

Test #12:

score: 0
Accepted
time: 10546ms
memory: 7188kb

input:

50
140 71 993 923
///////////////////////////\///////////////////////////////////////////
////////\////\/////////////////\\///\////\//////////////\/////\////////
/////////////////////\/\///////////\/////////////////////\/////////\///
\//////////////////\///////////////////\///////////////\//////////...

output:

255
1820 1837 2019 2656 2667 2671 2674 2677 2684 2692 2696 2699 2699 2700 2700 2703 2706 2717 2720 2723 2723 2726 2732 2734 2734 2736 2741 2742 2746 2747 2748 2749 2751 2752 2753 2755 2755 2758 2767 2770 2774 2782 2792 2812 2845 2847 2865 2884 3474 3558 3561 3596 3598 3607 3617 3629 3698 3698 3703 3...

result:

ok 100 lines