QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#601509#7775. 【模板】矩阵快速幂nhuang6850 124ms235544kbC++238.7kb2024-09-30 03:22:412024-09-30 03:22:41

Judging History

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

  • [2024-09-30 03:22:41]
  • 评测
  • 测评结果:0
  • 用时:124ms
  • 内存:235544kb
  • [2024-09-30 03:22:41]
  • 提交

answer

/**
 * @author n685
 * @brief
 * @date 2024-09-20 21:20:01
 *
 *
 */
#ifndef LOCAL
#pragma GCC optimize("O3,unroll-loops")
// #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#endif
#include "bits/stdc++.h"

#ifdef LOCAL
#include "dd/debug.h"
#else
#define dbg(...) 42
#define dbg_proj(...) 420
#define dbg_rproj(...) 420420
void nline() {}
void bar() {}
void start_clock() {}
void end_clock() {}
#endif

using i128 = __int128_t;

namespace rs = std::ranges;
namespace rv = std::views;

constexpr int MOD = 998'244'353;

using i128 = __int128_t;

template <class T>
concept integral = std::integral<T> || std::is_same_v<i128, T>;
// based on https://cp-algorithms.com/algebra/big-integer.html
struct BigInt {
  static constexpr int LG = 9;
  static constexpr int BASE = []() -> int {
    int ans = 1;
    for (int i = 0; i < LG; ++i) {
      ans *= 10;
    }
    return ans;
  }();
  std::vector<int> a;
  BigInt() = default;
  explicit BigInt(integral auto val) {
    while (val > 0) {
      a.push_back(static_cast<int>(val % BASE));
      val /= BASE;
    }
  }
  explicit BigInt(const std::string &s) {
    for (int i = static_cast<int>(s.size()) - 1; i >= 0; i -= BASE) {
      if (i < LG) {
        a.push_back(std::stoi(s.substr(0, i + 1)));
      } else {
        a.push_back(std::stoi(s.substr(i - LG + 1, LG)));
      }
    }
  }
  friend std::istream &operator>>(std::istream &in, BigInt &val) {
    std::string s;
    in >> s;
    val = BigInt{s};
    return in;
  }
  friend std::ostream &operator<<(std::ostream &out, const BigInt &val) {
    for (int i : val.a | rv::reverse) {
      out << i;
    }
    return out;
  }
  void trim() {
    while (!a.empty() && a.back() == 0) {
      a.pop_back();
    }
  }
  BigInt &operator+=(const BigInt &rhs) {
    int carry = 0;
    for (int i = 0; i < std::max(std::ssize(a), std::ssize(rhs.a)); ++i) {
      if (i == std::ssize(a)) {
        a.push_back(0);
      }
      a[i] += carry + (i < std::ssize(rhs.a) ? rhs.a[i] : 0);
      carry = (a[i] >= BASE) ? 1 : 0;
      if (a[i] >= BASE) {
        a[i] -= BASE;
      }
    }
    return *this;
  }
  BigInt &operator-=(const BigInt &rhs) {
    int carry = 0;
    for (int i = 0; i < std::ssize(rhs.a) || carry > 0; ++i) {
      a[i] -= carry + (i < std::ssize(rhs.a) ? rhs.a[i] : 0);
      carry = (a[i] < 0) ? 1 : 0;
      if (a[i] < 0) {
        a[i] += BASE;
      }
    }
    trim();
    return *this;
  }
  BigInt &operator*=(int rhs) {
    assert(rhs < BASE);
    int carry = 0;
    for (int i = 0; i < std::ssize(a) || carry > 0; ++i) {
      if (i == std::ssize(a)) {
        a.push_back(0);
      }
      int64_t cur = carry + int64_t{a[i]} * rhs;
      a[i] = static_cast<int>(cur % BASE);
      carry = static_cast<int>(cur / BASE);
    }
    return *this;
  }
  friend BigInt operator*(const BigInt &lhs, const BigInt &rhs) {
    BigInt ans;
    ans.a.resize(lhs.a.size() + rhs.a.size());
    for (int i = 0; i < std::ssize(lhs.a); ++i) {
      for (int j = 0, carry = 0; j < std::ssize(rhs.a) || carry > 0; ++j) {
        int64_t cur = ans.a[i + j]
          + int64_t{lhs.a[i]} * (j < std::ssize(rhs.a) ? rhs.a[j] : 0) + carry;
        ans.a[i + j] = static_cast<int>(cur % BASE);
        carry = static_cast<int>(cur / BASE);
      }
    }
    ans.trim();
    return ans;
  }
  BigInt &operator*=(const BigInt &rhs) { return *this = *this * rhs; }
  int div_mod(int rhs) {
    int carry = 0;
    for (int i = static_cast<int>(a.size()) - 1; i >= 0; --i) {
      int64_t cur = a[i] + int64_t{carry} * BASE;
      a[i] = static_cast<int>(cur / rhs);
      carry = static_cast<int>(cur % rhs);
    }
    trim();
    return carry;
  }
  BigInt &operator/=(int rhs) {
    div_mod(rhs);
    return *this;
  }
  int operator%(int rhs) {
    int carry = 0;
    for (int i = static_cast<int>(a.size()) - 1; i >= 0; --i) {
      carry = static_cast<int>((a[i] + int64_t{carry} * BASE) % rhs);
    }
    return carry;
  }
  bool operator==(const BigInt &rhs) const = default;
  bool operator!=(const BigInt &rhs) const = default;
  auto operator<=>(const BigInt &rhs) const {
    if (a.size() != rhs.a.size()) {
      return a.size() <=> rhs.a.size();
    }
    for (int i = static_cast<int>(a.size()) - 1; i >= 0; --i) {
      if (a[i] != rhs.a[i]) {
        return a[i] <=> rhs.a[i];
      }
    }
    return std::strong_ordering::equal;
  }
};
BigInt operator+(BigInt a, const BigInt &b) { return a += b; }
BigInt operator-(BigInt a, const BigInt &b) { return a -= b; }
BigInt operator*(BigInt a, int b) { return a *= b; }
BigInt operator*(int b, BigInt a) { return a *= b; }

#if defined(LOCAL) && __cplusplus >= 202302L
template <> struct std::formatter<BigInt, char> {
  std::formatter<std::string, char> underlying;
  constexpr formatter() {
    if constexpr (requires { underlying.set_debug_format(); }) {
      underlying.set_debug_format();
    }
  }
  template <class ParseContext> constexpr auto parse(ParseContext &ctx) {
    return underlying.parse(ctx);
  }
  template <class FormatContext>
  auto format(const BigInt &val, FormatContext &ctx) const {
    return underlying.format(std::stringstream{} << val, ctx);
  }
};
#endif

template <class T> constexpr T INF = T{};
template <std::floating_point T>
constexpr T INF<T> = std::numeric_limits<T>::infinity();
template <> constexpr int INF<int> = 0x3f3f3f3f; // 1061109567
template <>
constexpr int64_t INF<int64_t> = 0x3f3f3f3f3f3f3f3f; // 4557430888798830399
template <>
constexpr i128 INF<i128> = (static_cast<i128>(INF<int64_t>) << 64)
  | INF<int64_t>; // 84069761239290679208598432424319205183

struct Edge {
  int u, v;
  i128 w;
};

clock_t tot = 0;
clock_t tot2 = 0;
clock_t tot3 = 0;

void solve() {
  static_assert(integral<i128>);
  int n, m;
  std::string sk;
  std::cin >> n >> m >> sk;
  BigInt k(sk);

  std::vector<Edge> edges(m);
  for (auto &[u, v, w] : edges) {
    int64_t ww;
    std::cin >> u >> v >> ww;
    --u;
    --v;
    w = ww;
  }

  std::vector dist(n + 1, std::vector(n, std::vector<i128>(n, INF<i128>)));
  std::vector d0(10 * n * n + 1, std::vector<i128>(n, INF<i128>));
  d0[0][0] = 0;
  for (int i = 0; i < n; ++i) {
    dist[0][i][i] = 0;
  }
  for (int i = 1; i <= n; ++i) {
    for (int j = 0; j < n; ++j) {
      for (auto &[u, v, w] : edges) {
        dist[i][j][v] = std::min(dist[i][j][v], dist[i - 1][j][u] + w);
      }
    }
    d0[i] = dist[i][0];
  }
  for (int i = n + 1; i <= 10 * n * n; ++i) {
    for (auto &[u, v, w] : edges) {
      d0[i][v] = std::min(d0[i][v], d0[i - 1][u] + w);
    }
  }
  if (k <= BigInt{10 * n * n}) {
    int kk = std::stoi(sk);
    for (int i = 0; i < n; ++i) {
      if (d0[kk][i] == INF<i128>) {
        std::cout << "-1 ";
      } else {
        std::cout << static_cast<int>(d0[kk][i] % MOD) << ' ';
      }
    }
    std::cout << '\n';
    return;
  }

  std::vector dp(n * n + 1, std::vector<BigInt>(n));
  std::vector isinf(n * n + 1, std::vector<bool>(n, true));
  for (int i = 0; i < n; ++i) {
    i128 mi = INF<i128> / n;
    int sz = 1;
    for (int j = 1; j <= n; ++j) {
      if (dist[j][i][i] != INF<i128> && dist[j][i][i] * sz < mi * j) {
        mi = dist[j][i][i];
        sz = j;
      }
    }
    if (mi == INF<i128> / n) {
      continue;
    }
    for (int j = n * n - n; j <= n * n; ++j) {
      if (d0[j][i] == INF<i128>) {
        continue;
      }
      BigInt times = k - BigInt{j + n * n};
      int rem = times.div_mod(sz);
      int rest = n * n;
      if (rem > 0) {
        times += BigInt{1};
        rest -= sz - rem;
      }
      BigInt res = times * BigInt{mi} + BigInt{d0[j][i]};
      if (isinf[rest][i]) {
        dp[rest][i] = res;
      } else {
        dp[rest][i] = std::min(dp[rest][i], res);
      }
      isinf[rest][i] = false;
    }
  }
  std::vector<std::tuple<int, int, BigInt>> edges2;
  edges2.reserve(edges.size());
  for (auto [u, v, w] : edges) {
    edges2.emplace_back(u, v, w);
  }
  for (int i = n * n - 1; i >= 0; --i) {
    for (const auto &[u, v, w] : edges2) {
      if (!isinf[i + 1][u]) {
        if (isinf[i][v]) {
          dp[i][v] = dp[i + 1][u] + w;
        } else {
          dp[i][v] = std::min(dp[i][v], dp[i + 1][u] + w);
        }
        isinf[i][v] = false;
      }
    }
  }
  for (int i = 0; i < n; ++i) {
    if (isinf[0][i]) {
      std::cout << "-1 ";
    } else {
      std::cout << dp[0][i] % MOD << ' ';
    }
  }
  std::cout << '\n';
}

int main() {
#ifndef LOCAL
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
#endif
  // std::freopen("input.txt", "r", stdin);

  int s, t;
  std::cin >> s >> t;
  for (int i = 0; i < t; ++i) {
    solve();
  }
}

詳細信息

Subtask #1:

score: 0
Wrong Answer

Test #1:

score: 0
Wrong Answer
time: 124ms
memory: 235544kb

input:

1
1
100 101 899539897889989959
74 35 910832669819965536
35 85 910832669819965536
85 88 910832669819965536
88 30 910832669819965536
30 58 910832669819965536
58 60 910832669819965536
60 34 910832669819965536
34 8 910832669819965536
8 67 910832669819965536
67 89 910832669819965536
89 32 910832669819965...

output:

851410604 851410593 851410595 851410651 851410605 851410601 851410566 851410644 851410657 851410567 851410635 851410585 851410565 851410612 851410594 851410575 851410659 851410573 851410606 851410603 851410598 851410633 851410610 851410577 851410584 851410582 851410569 851410631 851410655 851410640 ...

result:

wrong answer 1st numbers differ - expected: '395495792', found: '851410604'

Subtask #2:

score: 0
Memory Limit Exceeded

Test #7:

score: 0
Memory Limit Exceeded

input:

2
1
300 598 8179377797889487867988994778539839593376697796496698959964978969
1 2 977880533270721156
2 1 977880533270721156
2 3 977880533270721156
3 2 977880533270721156
3 4 977880533270721156
4 3 977880533270721156
4 5 977880533270721156
5 4 977880533270721156
5 6 977880533270721156
6 5 977880533270...

output:

-1 911567081 -1 911556919 -1 911546757 -1 911536595 -1 911526433 -1 911516271 -1 911506109 -1 911495947 -1 911485785 -1 911475623 -1 911465461 -1 911455299 -1 911445137 -1 911434975 -1 911424813 -1 911414651 -1 911404489 -1 911394327 -1 911384165 -1 911374003 -1 911363841 -1 911353679 -1 911343517 -...

result:


Subtask #3:

score: 0
Skipped

Dependency #2:

0%

Subtask #4:

score: 0
Skipped

Dependency #1:

0%

Subtask #5:

score: 0
Skipped

Dependency #1:

0%

Subtask #6:

score: 0
Skipped

Dependency #3:

0%