結果
| 問題 | No.2151 3 on Torus-Lohkous |
| コンテスト | |
| ユーザー |
semiexp
|
| 提出日時 | 2022-12-09 23:47:16 |
| 言語 | C++17(clang) (17.0.6 + boost 1.87.0) |
| 結果 |
CE
(最新)
AC
(最初)
|
| 実行時間 | - |
| コード長 | 5,930 bytes |
| コンパイル時間 | 4,040 ms |
| コンパイル使用メモリ | 114,176 KB |
| 最終ジャッジ日時 | 2024-11-15 03:01:52 |
| 合計ジャッジ時間 | 4,524 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
コンパイルエラー時のメッセージ・ソースコードは、提出者また管理者しか表示できないようにしております。(リジャッジ後のコンパイルエラーは公開されます)
ただし、clay言語の場合は開発者のデバッグのため、公開されます。
ただし、clay言語の場合は開発者のデバッグのため、公開されます。
コンパイルメッセージ
main.cpp:24:31: error: no member named 'numeric_limits' in namespace 'std'
24 | static_assert(Mod <= std::numeric_limits<i32>::max());
| ~~~~~^
main.cpp:24:46: error: unexpected type name 'i32': expected expression
24 | static_assert(Mod <= std::numeric_limits<i32>::max());
| ^
main.cpp:24:50: error: no matching function for call to 'max'
24 | static_assert(Mod <= std::numeric_limits<i32>::max());
| ^~~~~
/usr/lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_algo.h:3461:5: note: candidate function template not viable: requires single argument '__l', but no arguments were provided
3461 | max(initializer_list<_Tp> __l)
| ^ ~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/algorithmfwd.h:407:5: note: candidate function template not viable: requires 2 arguments, but 0 were provided
407 | max(const _Tp&, const _Tp&);
| ^ ~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_algo.h:3467:5: note: candidate function template not viable: requires 2 arguments, but 0 were provided
3467 | max(initializer_list<_Tp> __l, _Compare __comp)
| ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/algorithmfwd.h:412:5: note: candidate function template not viable: requires 3 arguments, but 0 were provided
412 | max(const _Tp&, const _Tp&, _Compare);
| ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 errors generated.
ソースコード
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define MOD 998244353
#define ADD(X,Y) ((X) = ((X) + (Y)%MOD) % MOD)
typedef long long i64; typedef vector<int> ivec; typedef vector<string> svec;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
template <u32 Mod> class ModInt {
using Self = ModInt<Mod>;
static_assert(Mod <= std::numeric_limits<i32>::max());
public:
ModInt(i64 value = 0) {
if (value < 0) {
value_ = (Mod - (-value % Mod)) % Mod;
} else {
value_ = value % Mod;
}
}
ModInt(const Self& other) : value_(other.value_) {}
operator i32() const {
return value_;
}
operator i64() const {
return value_;
}
Self operator+(const Self& other) const {
Self res(*this);
res += other;
return res;
}
Self operator-(const Self& other) const {
Self res(*this);
res -= other;
return res;
}
Self operator*(const Self& other) const {
Self res(*this);
res *= other;
return res;
}
Self operator/(const Self& other) const {
Self res(*this);
res /= other;
return res;
}
Self operator-() const {
Self res(0);
res -= *this;
return res;
}
Self pow(i64 power) const {
Self ret(1), p(*this);
if (power < 0) {
power *= -1;
p = p.inv();
}
for (i64 i = 0; (1 << i) <= power; ++i) {
if ((power >> i) & 1) ret *= p;
p *= p;
}
return ret;
}
Self& operator+=(const Self& other) {
value_ += other.value_;
if (value_ >= Mod) value_ -= Mod;
return *this;
}
Self& operator-=(const Self& other) {
value_ += Mod - other.value_;
if (value_ >= Mod) value_ -= Mod;
return *this;
}
Self& operator*=(const Self& other) {
value_ = (u32)(((u64)value_ * other.value_) % Mod);
return *this;
}
Self& operator/=(const Self& other) {
*this *= other.inv();
return *this;
}
Self inv() const {
if (value_ < inv_tbl_.size()) return inv_tbl_[value_];
if (Mod - value_ < inv_tbl_.size()) return Mod - inv_tbl_[Mod - value_];
else return pow(Mod - 2);
}
private:
u32 value_;
static const std::vector<Self> inv_tbl_;
};
template <u32 Mod>
std::vector<ModInt<Mod>> create_inv_tbl_(u32 n) {
std::vector<ModInt<Mod>> res;
res.reserve(n + 1);
res.push_back(0);
res.push_back(1);
for (u32 i = 2; i <= n; ++i) {
// MOD / i == 0
// MOD // i + (MOD % i) / i == 0
// 1 / i == -(MOD // i) / (MOD % i)
res.push_back(res[Mod % i] * ModInt<Mod>(Mod - (Mod / i)));
}
return res;
}
template <u32 Mod>
const std::vector<ModInt<Mod>> ModInt<Mod>::inv_tbl_ = create_inv_tbl_<Mod>(1000000);
template <class T, u32 Mod>
ModInt<Mod> operator+(T x, ModInt<Mod> y) {
return ModInt<Mod>(x) + y;
}
template <class T, u32 Mod>
ModInt<Mod> operator-(T x, ModInt<Mod> y) {
return ModInt<Mod>(x) - y;
}
template <class T, u32 Mod>
ModInt<Mod> operator*(T x, ModInt<Mod> y) {
return ModInt<Mod>(x) * y;
}
template <class T, u32 Mod>
ModInt<Mod> operator/(T x, ModInt<Mod> y) {
return ModInt<Mod>(x) / y;
}
template <class T, u32 Mod>
ModInt<Mod> operator+(ModInt<Mod> x, T y) {
return x + ModInt<Mod>(y);
}
template <class T, u32 Mod>
ModInt<Mod> operator-(ModInt<Mod> x, T y) {
return x - ModInt<Mod>(y);
}
template <class T, u32 Mod>
ModInt<Mod> operator*(ModInt<Mod> x, T y) {
return x * ModInt<Mod>(y);
}
template <class T, u32 Mod>
ModInt<Mod> operator/(ModInt<Mod> x, T y) {
return x / ModInt<Mod>(y);
}
typedef ModInt<MOD> mint;
int T;
int H, W;
mint fact[101010], facti[101010];
mint C(int x, int y) {
if (0 <= y && y <= x) {
return fact[x] * facti[x - y] * facti[y];
} else {
return 0;
}
}
int mygcd(int x, int y) {
while (y) {
int tmp = x % y;
x = y;
y = tmp;
}
return x;
}
mint solve(int H, int W) {
mint ans = 0;
ans += mint(H) * mint(W);
if (H % 4 == 0 && W % 4 == 0) {
ans += 16;
}
int g = mygcd(H, W);
if (g >= 4) {
ans += 2 * g;
}
if (g >= 5 && (H % 3 == 0 || W % 3 == 0)) {
ans += g * 12;
}
/*
if (g % 2 == 0) {
int g2 = g / 2;
mint tmp = 0;
for (int n5 = 1; n5 <= g2 / 5; ++n5) {
if ((g2 - 5 * n5) % 3 != 0) continue;
int n3 = (g2 - 5 * n5) / 3;
// printf("%d %d\n", n5, n3);
if (n5 >= 1) tmp += C(n5 - 1 + n3, n5 - 1) * 5;
if (n3 >= 1) tmp += C(n5 + n3 - 1, n3 - 1) * 3;
}
// printf("%d\n", (int)tmp);
ans += tmp * tmp * 4;
}
*/
if (g % 2 == 0) {
int g2 = g / 2;
mint tmp[2] = {0, 0};
for (int n5 = 1; n5 <= g2 / 5; ++n5) {
if ((g2 - 5 * n5) % 3 != 0) continue;
int n3 = (g2 - 5 * n5) / 3;
// printf("%d %d\n", n5, n3);
if (n5 >= 1) tmp[n5 % 2] += C(n5 - 1 + n3, n5 - 1) * 5;
if (n3 >= 1) tmp[n5 % 2] += C(n5 + n3 - 1, n3 - 1) * 3;
}
ans += tmp[0] * tmp[0] * 4;
ans += tmp[1] * tmp[1] * 4;
// printf("%d\n", (int)tmp);
}
return ans;
}
int main()
{
fact[0] = facti[0] = 1;
for (int i = 1; i < 101010; ++i) {
fact[i] = fact[i - 1] * i;
facti[i] = facti[i - 1] / i;
}
scanf("%d", &T);
for (;T--;) {
scanf("%d%d", &H, &W);
mint ans = solve(H, W);
printf("%d\n", (int)ans);
}
return 0;
}
semiexp