QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#592884 | #7775. 【模板】矩阵快速幂 | nhuang685 | 0 | 0ms | 0kb | C++23 | 8.9kb | 2024-09-27 09:26:28 | 2024-09-27 09:26:28 |
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;
template <class T>
concept integral = std::integral<T> || std::is_same_v<T, i128>;
struct BigInt {
using T = i128;
static constexpr T BASE = 1000000000000;
static constexpr int LG = 12;
// std::vector<T> digits;
std::array<T, 12> digits{};
BigInt() = default;
explicit BigInt(integral auto val) {
int ind = 0;
while (val > 0) {
// digits.push_back(val % BASE);
digits[ind++] = val % BASE;
val /= BASE;
}
}
explicit BigInt(std::string s) {
// for (char c : s | rv::reverse) {
// digits.push_back(c - '0');
// }
std::reverse(s.begin(), s.end());
s.resize((s.size() + LG - 1) / LG * LG, '0');
int ind = -1;
for (int i = 0; i < std::ssize(s); i += LG) {
// digits.push_back(0);
++ind;
T mul = 1;
for (int j = 0; j < LG && i + j < std::ssize(s); ++j, mul *= 10) {
// digits.back() += (s[i + j] - '0') * mul;
digits[ind] += (s[i + j] - '0') * mul;
}
}
}
// void trim() {
// while (!digits.empty() && digits.back() == 0) {
// digits.pop_back();
// }
// }
void carry() {
for (int i = 0; i < std::ssize(digits); ++i) {
if (digits[i] < BASE) {
continue;
}
// if (i == std::ssize(digits) - 1) {
// digits.push_back(0);
// }
digits[i + 1] += digits[i] / BASE;
digits[i] %= BASE;
}
}
// value needs to be nonnegative
void deneg() {
for (int i = 0; i < std::ssize(digits) - 1; ++i) {
if (digits[i] >= 0) {
continue;
}
T val = ((BASE - 1) - digits[i]) / BASE;
digits[i + 1] -= val;
digits[i] += BASE * val;
}
// trim();
}
BigInt &operator+=(const BigInt &rhs) {
// digits.resize(std::max(digits.size(), rhs.digits.size()));
for (int i = 0; i < std::min(std::ssize(digits), std::ssize(rhs.digits));
++i)
{
digits[i] += rhs.digits[i];
}
carry();
return *this;
}
BigInt &operator+=(integral auto rhs) {
// for (int i = 0; rhs > 0; ++i) {
// if (i == std::ssize(digits)) {
// digits.push_back(rhs % BASE);
// } else {
// digits[i] += rhs % BASE;
// }
// rhs /= BASE;
// }
// if (digits.empty()) {
// digits.push_back(0);
// }
digits[0] += rhs;
carry();
return *this;
}
BigInt &operator-=(const BigInt &rhs) {
assert(digits.size() >= rhs.digits.size());
for (int i = 0; i < std::ssize(rhs.digits); ++i) {
digits[i] -= rhs.digits[i];
}
deneg();
return *this;
}
BigInt &operator-=(integral auto rhs) {
for (int i = 0; rhs > 0; ++i) {
digits[i] -= rhs % BASE;
rhs /= BASE;
}
deneg();
return *this;
}
BigInt operator*(const BigInt &rhs) {
if (digits.empty() || rhs.digits.empty()) {
return BigInt{};
}
BigInt ans;
// ans.digits.resize(digits.size() + rhs.digits.size() - 1);
for (int i = 0; i < std::ssize(digits); ++i) {
for (int j = 0; j < std::ssize(rhs.digits); ++j) {
ans.digits[i + j] += digits[i] * rhs.digits[j];
}
}
ans.carry();
// ans.trim();
return ans;
}
BigInt &operator*=(integral auto rhs) {
for (T &i : digits) {
i *= rhs;
}
return *this;
}
std::pair<BigInt, int> div(int rhs) const {
BigInt ans;
T rem = 0;
int ind = 0;
for (T i : digits | rv::reverse) {
rem = rem * BASE + i;
// ans.digits.push_back(rem / rhs);
ans.digits[ind++] = rem / rhs;
rem %= rhs;
}
rs::reverse(ans.digits);
return {ans, static_cast<int>(rem)};
}
int operator%(int rhs) const {
int val = 0;
for (T i : digits | rv::reverse) {
val
= static_cast<int>((static_cast<int64_t>(val) * BASE % rhs + i) % rhs);
}
return val;
}
bool operator==(const BigInt &rhs) const = default;
bool operator!=(const BigInt &rhs) const = default;
auto operator<=>(const BigInt &rhs) const {
if (digits.size() != rhs.digits.size()) {
return digits.size() <=> rhs.digits.size();
}
for (int i = static_cast<int>(digits.size()) - 1; i >= 0; --i) {
if (digits[i] != rhs.digits[i]) {
return digits[i] <=> rhs.digits[i];
}
}
return std::strong_ordering::equal;
}
};
BigInt operator+(BigInt a, const BigInt &b) { return a += b; }
BigInt operator+(BigInt a, integral auto b) { return a += b; }
BigInt operator-(BigInt a, const BigInt &b) { return a -= b; }
BigInt operator-(BigInt a, integral auto b) { return a -= b; }
BigInt operator*(BigInt a, integral auto b) { return a *= b; }
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;
}
auto start2 = clock();
std::vector dist(n + 1, std::vector(n, std::vector<i128>(n, INF<i128>)));
std::vector d0(2 * 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 <= 2 * n * n; ++i) {
for (auto &[u, v, w] : edges) {
d0[i][v] = std::min(d0[i][v], d0[i - 1][u] + w);
}
}
tot2 += clock() - start2;
if (k <= BigInt{2 * 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;
}
auto start3 = clock();
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;
}
auto [times, rem] = (k - (j + n * n)).div(sz);
int rest = n * n;
if (rem > 0) {
times += 1;
rest -= sz - rem;
}
BigInt res = times * mi + 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;
}
}
tot3 += clock() - start3;
auto start = clock();
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;
}
}
}
tot += clock() - start;
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;
start_clock();
for (int i = 0; i < t; ++i) {
// dbg(i + 1);
solve();
// bar();
}
end_clock();
dbg(tot2);
dbg(tot3);
dbg(tot);
}
详细
Subtask #1:
score: 0
Runtime Error
Test #1:
score: 0
Runtime Error
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:
result:
Subtask #2:
score: 0
Runtime Error
Test #7:
score: 0
Runtime Error
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:
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%