結果
問題 |
No.5021 Addition Pyramid
|
ユーザー |
![]() |
提出日時 | 2025-02-25 21:13:37 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 1,716 ms / 2,000 ms |
コード長 | 5,244 bytes |
コンパイル時間 | 6,262 ms |
コンパイル使用メモリ | 334,440 KB |
実行使用メモリ | 6,820 KB |
スコア | 220,876,595 |
最終ジャッジ日時 | 2025-02-25 21:15:07 |
合計ジャッジ時間 | 87,131 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
純コード判定しない問題か言語 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 50 |
ソースコード
#include <atcoder/all> #include <bits/stdc++.h> using ll = long long; using ull = unsigned long long; #define rep(i, n) for(int i = 0; i < (int)(n); i++) #define REP(i, m, n) for(int i = (int)(m); i < (int)(n); i++) using namespace std; using namespace atcoder; using mint = modint998244353; const int inf = 1000000007; const ll longinf = 1ll << 60; struct Timer { chrono::system_clock::time_point start, last_updated; Timer() { start = chrono::system_clock::now(); last_updated = chrono::system_clock::now(); } void reset() { start = chrono::system_clock::now(); } void update() { last_updated = chrono::system_clock::now(); } double getTime() { auto now = chrono::system_clock::now(); return chrono::duration<double>(now - start).count(); } }; Timer timer; struct Xor128 { unsigned x, y, z, w; Xor128() : x(123456789), y(362436069), z(521288629), w(88675123){}; inline unsigned xor128() { unsigned t; t = x ^ (x << 11); x = y; y = z; z = w; return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)); } int nextInt(int x, int y) { return xor128() % (y - x) + x; } double nextDouble(double a, double b) { return (double)(xor128() & 0xffff) / 0xffff * (b - a) + a; } }; auto rnd = Xor128(); const int N = 50; const int mod = 100000000; int a[N][N]; inline int calc_diff(int x, int y) { int diff = abs(x - y); return min(diff, mod - diff); } vector<int> create_next_row(vector<int> &prv, int diff) { int m = prv.size(); int s = 0; vector<pair<int, int>> segs; rep(i, m + 1) { if(i % 2 == 0) { // a-diff <= x + s <= a + diff // a - s - diff <= x <= a - s + diff int l = a[m][i] - s - diff; int r = a[m][i] - s + diff; while(l < 0) { l += mod; r += mod; } if(r < mod) { segs.push_back({l, 1}); segs.push_back({r, -1}); } else { segs.push_back({l, 1}); segs.push_back({mod, -1}); segs.push_back({0, 1}); segs.push_back({r - mod, -1}); } } else { // a-diff <= -x + s <= a + diff // a - s - diff <= -x <= a - s + diff // s - a - diff <= x <= a - s - diff; int l = s - a[m][i] - diff; int r = s - a[m][i] + diff; while(l < 0) { l += mod; r += mod; } assert(r - l <= mod); if(r < mod) { segs.push_back({l, 1}); segs.push_back({r, -1}); } else { segs.push_back({l, 1}); segs.push_back({mod, -1}); segs.push_back({0, 1}); segs.push_back({r - mod, -1}); } } if(i != m) { s = (mod + prv[i] - s) % mod; } } sort(segs.begin(), segs.end()); int c = 0; int target = -1; for(auto [v, sgn] : segs) { c += sgn; if(c == m + 1) { target = v; break; } } if(target == -1) { return vector<int>(); } else { vector<int> ret(m + 1); int s = 0; rep(i, m + 1) { if(i % 2 == 0) { ret[i] = (target + s) % mod; } else { ret[i] = (mod - target + s) % mod; } s = (mod + prv[i] - s) % mod; } return ret; } } void input() { int _; cin >> _; rep(i, N) { rep(j, i + 1) cin >> a[i][j]; } } int evaluate(vector<int> &c) { vector<vector<int>> ans(N, vector(N, 0)); rep(i, N) ans[N - 1][i] = c[i]; int max_diff = 0; for(int i = N - 2; i >= 0; i--) { for(int j = 0; j <= i; j++) { ans[i][j] = (ans[i + 1][j] + ans[i + 1][j + 1]) % mod; int diff = abs(ans[i][j] - a[i][j]); max_diff = max(max_diff, min(diff, mod - diff)); } } return max_diff; } void output(vector<int> &c) { rep(i, N) cout << c[i] << " \n"[i + 1 == N]; cerr << evaluate(c) << endl; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); input(); int min_score = mod; vector<int> ans; rep(_, 1000) { vector<int> cur = {rnd.nextInt(0, mod)}; int score = calc_diff(a[0][0], cur[0]); if(score >= min_score) { continue; } rep(turn, N - 1) { int ok = mod, ng = 0; while(ok - ng > 1) { int mid = (ok + ng) / 2; auto ret = create_next_row(cur, mid); if(ret.size() > 0) { ok = mid; } else { ng = mid; } } cur = create_next_row(cur, ok); score = max(score, ok); if(score >= min_score) { break; } } if(score < min_score) { ans = cur; min_score = score; } } output(ans); return 0; }