結果
| 問題 | No.3416 マッチ棒パズル Extra |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2026-01-05 14:44:31 |
| 言語 | C++17 (gcc 15.2.0 + boost 1.89.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 3,025 bytes |
| 記録 | |
| コンパイル時間 | 850 ms |
| コンパイル使用メモリ | 111,116 KB |
| 実行使用メモリ | 19,408 KB |
| 最終ジャッジ日時 | 2026-01-05 14:44:41 |
| 合計ジャッジ時間 | 9,314 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | TLE * 1 -- * 25 |
ソースコード
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
/**
* @brief 高速入出力テンプレ
*/
struct FastIO {
FastIO() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
}
inline long long read() {
long long x;
if (!(cin >> x)) return -1;
return x;
}
inline void print(long long x) { cout << x << "\n"; }
} io;
/**
* @brief 自動で Mod を取る整数型
*/
template<int mod>
struct Mint {
long long v;
Mint(long long _v = 0) : v((_v % mod + mod) % mod) {}
Mint operator+(const Mint& o) const { return Mint(v + o.v); }
Mint operator-(const Mint& o) const { return Mint(v - o.v); }
Mint operator*(const Mint& o) const { return Mint(v * o.v); }
friend ostream& operator<<(ostream& os, const Mint& m) { return os << m.v; }
};
using modint = Mint<998244353>;
/**
* @brief 格子点計数クラス
* 2xy + x + y <= N (x, y >= 1) を満たす整数の組
*/
struct LatticeCounter {
using i128 = __int128_t;
// (2x+1)(2y+1) <= K を満たす x > y >= 1 の個数を SBT で求める
modint count_points(long long n) {
long long k = 2 * n + 1;
long long border = (sqrt(k) - 1) / 2;
while ((i128)(2 * border + 3) * (2 * border + 3) <= k) border++;
while ((i128)(2 * border + 1) * (2 * border + 1) > k) border--;
if (border < 1) return modint(0);
long long x = border + 1;
long long y = (k / (2 * x + 1) - 1) / 2;
if (y < 0) y = 0;
modint res = 0;
long long limit_y = pow(k, 1.0 / 3.0);
auto is_inside = [&](long long tx, long long ty) {
return (i128)(2 * tx + 1) * (2 * ty + 1) <= k;
};
// Stern-Brocot Tree による境界追跡
auto dfs = [&](auto self, long long dx1, long long dy1, long long dx2, long long dy2) -> void {
while (is_inside(x + dx1, y - dy1)) {
if (y <= dy1) break;
res = res + modint(x - border) * dy1 + modint(dy1) * (dx1 - 1) * 499122177; // 499122177 は 2 の逆数
x += dx1; y -= dy1;
}
if (y <= limit_y) return;
long long mx = dx1 + dx2, my = dy1 + dy2;
if (is_inside(x + mx, y - my)) {
self(self, mx, my, dx2, dy2);
} else {
if ((i128)(2 * y + 1) * mx <= (i128)(2 * x + 1) * my) return;
self(self, dx1, dy1, mx, my);
}
};
dfs(dfs, 1, 0, 0, 1);
for (long long i = 1; i <= y; ++i) {
long long cur_x = (k / (2 * i + 1) - 1) / 2;
if (cur_x > border) res = res + modint(cur_x - border);
}
return res * 2 + modint(border);
}
};
void solve() {
long long n = io.read();
if (n < 0) return;
LatticeCounter lc;
io.print(lc.count_points(n).v);
}
int main() {
int t = io.read();
while (t-- > 0) {
solve();
}
return 0;
}