QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#241278#7686. The Phantom Menaceucup-team987#WA 595ms3532kbC++2310.7kb2023-11-06 01:16:412023-11-06 01:16:41

Judging History

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

  • [2024-10-08 14:11:03]
  • hack成功,自动添加数据
  • (/hack/941)
  • [2024-10-08 10:05:28]
  • hack成功,自动添加数据
  • (/hack/940)
  • [2024-10-07 19:51:15]
  • hack成功,自动添加数据
  • (/hack/938)
  • [2024-10-07 19:28:01]
  • hack成功,自动添加数据
  • (/hack/937)
  • [2024-10-07 17:16:32]
  • hack成功,自动添加数据
  • (/hack/936)
  • [2024-10-07 16:53:09]
  • hack成功,自动添加数据
  • (/hack/935)
  • [2024-10-07 16:22:17]
  • hack成功,自动添加数据
  • (/hack/934)
  • [2023-11-06 01:16:41]
  • 评测
  • 测评结果:WA
  • 用时:595ms
  • 内存:3532kb
  • [2023-11-06 01:16:41]
  • 提交

answer

#if __INCLUDE_LEVEL__ == 0

#include __BASE_FILE__

namespace {

void solve() {
  int n, m;
  scan(n, m);
  vector<roriha> a(n);
  for (int i : rep(n)) {
    string s;
    scan(s);
    a[i] = s;
  }
  vector<roriha> b(n);
  for (int i : rep(n)) {
    string s;
    scan(s);
    b[i] = s;
  }

  {
    vector<pair<roriha::Hash, int>> va(n);
    vector<pair<roriha::Hash, int>> vb(n);
    for (int i : rep(n)) {
      va[i] = {a[i].get(0, m), i + 1};
      vb[i] = {b[i].get(0, m), i + 1};
    }
    ranges::sort(va);
    ranges::sort(vb);
    if (ranges::equal(va | views::keys, vb | views::keys)) {
      print(va | views::values);
      print(vb | views::values);
      return;
    }
  }

  for (int r : rep(1, m)) {
    vector<roriha::Hash> vl;
    vector<roriha::Hash> vr;
    for (int i : rep(n)) {
      vl.push_back(a[i].get(0, r));
      vl.push_back(b[i].get(m - r, m));
      vr.push_back(a[i].get(r, m));
      vr.push_back(b[i].get(0, m - r));
    }
    ranges::sort(vl);
    ranges::sort(vr);
    ALL(vl.erase, ranges::unique(vl));
    ALL(vr.erase, ranges::unique(vr));
    vector<vector<pair<int, int>>> g(len(vl) + len(vr));
    for (int i : rep(n)) {
      int from = ranges::lower_bound(vl, a[i].get(0, r)) - vl.begin();
      int to = ranges::lower_bound(vr, a[i].get(r, m)) - vr.begin() + len(vl);
      g[from].emplace_back(to, i);
    }
    for (int i : rep(n)) {
      int from =
          ranges::lower_bound(vr, b[i].get(0, m - r)) - vr.begin() + len(vl);
      int to = ranges::lower_bound(vl, b[i].get(m - r, m)) - vl.begin();
      g[from].emplace_back(to, n + i);
    }
    auto walk = kactl::eulerWalk(g, n * 2);
    if (walk.empty()) {
      continue;
    }
    assert(len(walk) == n * 2 + 1);
    vector<int> ans_a(n);
    vector<int> ans_b(n);
    for (int i : rep(n)) {
      ans_a[i] = walk[i * 2 + 1].second + 1;
      ans_b[i] = walk[i * 2 + 2].second + 1 - n;
    }
    print(ans_a);
    print(ans_b);
    return;
  }

  print(-1);
}

}  // namespace

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  int t;
  scan(t);
  while (t--) {
    solve();
  }
}

#else  // __INCLUDE_LEVEL__

#include <bits/stdc++.h>

using namespace std;

#define ALL(f, r, ...) \
  [&](auto&& _) { return f(begin(_), end(_), ##__VA_ARGS__); }(r)

namespace std {

template <class T1, class T2>
istream& operator>>(istream& is, pair<T1, T2>& p) {
  return is >> p.first >> p.second;
}

template <class... Ts>
istream& operator>>(istream& is, tuple<Ts...>& t) {
  return apply([&is](auto&... xs) -> istream& { return (is >> ... >> xs); }, t);
}

template <class R, enable_if_t<!is_convertible_v<R, string>>* = nullptr>
auto operator>>(istream& is, R&& r) -> decltype(is >> *begin(r)) {
  for (auto&& e : r) {
    is >> e;
  }
  return is;
}

template <class T1, class T2>
ostream& operator<<(ostream& os, const pair<T1, T2>& p) {
  return os << p.first << ' ' << p.second;
}

template <class... Ts>
ostream& operator<<(ostream& os, const tuple<Ts...>& t) {
  auto f = [&os](const auto&... xs) -> ostream& {
    [[maybe_unused]] auto sep = "";
    ((os << exchange(sep, " ") << xs), ...);
    return os;
  };
  return apply(f, t);
}

template <class R, enable_if_t<!is_convertible_v<R, string_view>>* = nullptr>
auto operator<<(ostream& os, R&& r) -> decltype(os << *begin(r)) {
  auto sep = "";
  for (auto&& e : r) {
    os << exchange(sep, " ") << e;
  }
  return os;
}

}  // namespace std

void scan(auto&&... xs) { (cin >> ... >> xs); }
void print(auto&&... xs) { cout << tie(xs...) << '\n'; }

inline auto rep(int l, int r) { return views::iota(min(l, r), r); }
inline auto rep(int n) { return rep(0, n); }
inline auto rep1(int l, int r) { return rep(l, r + 1); }
inline auto rep1(int n) { return rep(1, n + 1); }
inline auto per(int l, int r) { return rep(l, r) | views::reverse; }
inline auto per(int n) { return per(0, n); }
inline auto per1(int l, int r) { return per(l, r + 1); }
inline auto per1(int n) { return per(1, n + 1); }

inline auto len = ranges::ssize;

// https://nyaannyaan.github.io/library/string/rolling-hash.hpp
namespace internal {

using i64 = long long;
using u64 = unsigned long long;
using u128 = __uint128_t;

template <int BASE_NUM = 2>
struct Hash : array<u64, BASE_NUM> {
  using array<u64, BASE_NUM>::operator[];
  static constexpr int n = BASE_NUM;

  Hash() : array<u64, BASE_NUM>() {}

  static constexpr u64 md = (1ull << 61) - 1;

  constexpr static Hash set(const i64& a) {
    Hash res;
    fill(begin(res), end(res), cast(a));
    return res;
  }
  Hash& operator+=(const Hash& r) {
    for (int i = 0; i < n; i++)
      if (((*this)[i] += r[i]) >= md) (*this)[i] -= md;
    return *this;
  }
  Hash& operator+=(const i64& r) {
    u64 s = cast(r);
    for (int i = 0; i < n; i++)
      if (((*this)[i] += s) >= md) (*this)[i] -= md;
    return *this;
  }
  Hash& operator-=(const Hash& r) {
    for (int i = 0; i < n; i++)
      if (((*this)[i] += md - r[i]) >= md) (*this)[i] -= md;
    return *this;
  }
  Hash& operator-=(const i64& r) {
    u64 s = cast(r);
    for (int i = 0; i < n; i++)
      if (((*this)[i] += md - s) >= md) (*this)[i] -= md;
    return *this;
  }
  Hash& operator*=(const Hash& r) {
    for (int i = 0; i < n; i++) (*this)[i] = modmul((*this)[i], r[i]);
    return *this;
  }
  Hash& operator*=(const i64& r) {
    u64 s = cast(r);
    for (int i = 0; i < n; i++) (*this)[i] = modmul((*this)[i], s);
    return *this;
  }

  Hash operator+(const Hash& r) { return Hash(*this) += r; }
  Hash operator+(const i64& r) { return Hash(*this) += r; }
  Hash operator-(const Hash& r) { return Hash(*this) -= r; }
  Hash operator-(const i64& r) { return Hash(*this) -= r; }
  Hash operator*(const Hash& r) { return Hash(*this) *= r; }
  Hash operator*(const i64& r) { return Hash(*this) *= r; }
  Hash operator-() const {
    Hash res;
    for (int i = 0; i < n; i++) res[i] = (*this)[i] == 0 ? 0 : md - (*this)[i];
    return res;
  }
  friend Hash pfma(const Hash& a, const Hash& b, const Hash& c) {
    Hash res;
    for (int i = 0; i < n; i++) res[i] = modfma(a[i], b[i], c[i]);
    return res;
  }
  friend Hash pfma(const Hash& a, const Hash& b, const i64& c) {
    Hash res;
    u64 s = cast(c);
    for (int i = 0; i < n; i++) res[i] = modfma(a[i], b[i], s);
    return res;
  }

  Hash pow(long long e) {
    Hash a{*this}, res{Hash::set(1)};
    for (; e; a *= a, e >>= 1) {
      if (e & 1) res *= a;
    }
    return res;
  }

  static Hash get_basis() {
    static auto rand_time =
        chrono::duration_cast<chrono::nanoseconds>(
            chrono::high_resolution_clock::now().time_since_epoch())
            .count();
    static mt19937_64 rng(rand_time);
    Hash h;
    for (int i = 0; i < n; i++) {
      while (isPrimitive(h[i] = rng() % (md - 1) + 1) == false)
        ;
    }
    return h;
  }

 private:
  static u64 modpow(u64 a, u64 b) {
    u64 r = 1;
    for (a %= md; b; a = modmul(a, a), b >>= 1) r = modmul(r, a);
    return r;
  }
  static bool isPrimitive(u64 x) {
    for (auto& d : vector<u64>{2, 3, 5, 7, 11, 13, 31, 41, 61, 151, 331, 1321})
      if (modpow(x, (md - 1) / d) <= 1) return false;
    return true;
  }
  static inline constexpr u64 cast(const long long& a) {
    return a < 0 ? a + md : a;
  }
  static inline constexpr u64 modmul(const u64& a, const u64& b) {
    u128 d = u128(a) * b;
    u64 ret = (u64(d) & md) + u64(d >> 61);
    return ret >= md ? ret - md : ret;
  }
  static inline constexpr u64 modfma(const u64& a, const u64& b, const u64& c) {
    u128 d = u128(a) * b + c;
    u64 ret = (d >> 61) + (u64(d) & md);
    return ret >= md ? ret - md : ret;
  }
};

}  // namespace internal

template <typename Str, int BASE_NUM = 2>
struct RollingHash {
  using Hash = internal::Hash<BASE_NUM>;
  Str data;
  vector<Hash> hs, pw;
  int s;
  static Hash basis;

  RollingHash(const Str& S = Str()) { build(S); }

  void build(const Str& S) {
    data = S;
    s = S.size();
    hs.resize(s + 1);
    pw.resize(s + 1);
    pw[0] = Hash::set(1);
    hs[0] = Hash::set(0);
    for (int i = 1; i <= s; i++) {
      pw[i] = pw[i - 1] * basis;
      hs[i] = pfma(hs[i - 1], basis, S[i - 1]);
    }
  }

  Hash get(int l, int r = -1) const {
    if (r == -1) r = s;
    return pfma(hs[l], -pw[r - l], hs[r]);
  }

  static Hash get_hash(const Str& T) {
    Hash ret = Hash::set(0);
    for (int i = 0; i < (int)T.size(); i++) ret = pfma(ret, basis, T[i]);
    return ret;
  }

  static Hash unite(Hash a, Hash b, long long bsize) {
    return pfma(a, basis.pow(bsize), b);
  }

  int find(Str& T, int lower = 0) const {
    auto ths = get_hash(T);
    for (int i = lower; i <= s - (int)T.size(); i++)
      if (ths == get(i, i + (int)T.size())) return i;
    return -1;
  }

  static int lcp(const RollingHash& a, const RollingHash& b, int al, int bl) {
    int ok = 0, ng = min(a.size() - al, b.size() - bl) + 1;
    while (ok + 1 < ng) {
      int med = (ok + ng) / 2;
      (a.get(al, med + al) == b.get(bl, med + bl) ? ok : ng) = med;
    }
    return ok;
  }

  static int strcmp(const RollingHash& a, const RollingHash& b, int al, int bl,
                    int ar = -1, int br = -1) {
    if (ar == -1) ar = a.size();
    if (br == -1) br = b.size();
    int n = min<int>({lcp(a, b, al, bl), ar - al, br - bl});
    return al + n == ar                      ? bl + n == br ? 0 : -1
           : bl + n == br                    ? 1
           : a.data[al + n] < b.data[bl + n] ? -1
                                             : 1;
  }

  int size() const { return s; }
};

template <typename Str, int BASE_NUM>
typename RollingHash<Str, BASE_NUM>::Hash RollingHash<Str, BASE_NUM>::basis =
    internal::Hash<BASE_NUM>::get_basis();
using roriha = RollingHash<string, 2>;

// https://github.com/kth-competitive-programming/kactl
namespace kactl {

#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

vector<pii> eulerWalk(vector<vector<pii>>& gr, int nedges, int src = 0) {
  int n = sz(gr);
  vi D(n), its(n), eu(nedges);
  vector<pii> ret, s = {{src, -1}};
  D[src]++;
  while (!s.empty()) {
    int x = s.back().first, y, e, &it = its[x], end = sz(gr[x]);
    if (it == end) {
      ret.emplace_back(x, s.back().second);
      s.pop_back();
      continue;
    }
    tie(y, e) = gr[x][it++];
    if (!eu[e]) {
      D[x]--, D[y]++;
      eu[e] = 1;
      s.emplace_back(y, e);
    }
  }
  for (int x : D)
    if (x < 0 || sz(ret) != nedges + 1) return {};
  return {ret.rbegin(), ret.rend()};
}

#undef sz

}  // namespace kactl

#endif  // __INCLUDE_LEVEL__

詳細信息

Test #1:

score: 100
Accepted
time: 1ms
memory: 3408kb

input:

2
3 3
abc
ghi
def
bcd
efg
hia
1 3
abc
def

output:

1 3 2
1 2 3
-1

result:

ok 2 cases (2 test cases)

Test #2:

score: 0
Accepted
time: 595ms
memory: 3528kb

input:

1000000
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
b
b
1 1
a
b
1 1
b
a
1 1
a
a
1 1
...

output:

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
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
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
1
1
-1
-1
1
1
1
1
-1
-1
1
1
1
1
-1
-1
1
1
1
1
-1...

result:

ok 1000000 cases (1000000 test cases)

Test #3:

score: -100
Wrong Answer
time: 483ms
memory: 3532kb

input:

500000
1 2
dd
ba
1 2
cd
ba
1 2
bd
ba
1 2
ad
ba
1 2
dc
ba
1 2
cc
ba
1 2
bc
ba
1 2
ac
ba
1 2
db
ba
1 2
cb
ba
1 2
bb
ba
1 2
ab
ba
1 2
da
ba
1 2
ca
ba
1 2
ba
ba
1 2
aa
ba
1 2
dd
aa
1 2
cd
aa
1 2
bd
aa
1 2
ad
aa
1 2
dc
aa
1 2
cc
aa
1 2
bc
aa
1 2
ac
aa
1 2
db
aa
1 2
cb
aa
1 2
bb
aa
1 2
ab
aa
1 2
da
aa
1 2...

output:

-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
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
-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
-1
-1
1
1
1
...

result:

wrong answer not cyclic isomorphism (test case 34)