結果
問題 |
No.5021 Addition Pyramid
|
ユーザー |
![]() |
提出日時 | 2025-03-01 10:47:18 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 1,815 ms / 2,000 ms |
コード長 | 7,775 bytes |
コンパイル時間 | 6,952 ms |
コンパイル使用メモリ | 335,716 KB |
実行使用メモリ | 6,824 KB |
スコア | 2,094,821 |
最終ジャッジ日時 | 2025-03-01 10:49:00 |
合計ジャッジ時間 | 101,066 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge6 |
純コード判定しない問題か言語 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
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 + 1][N + 1]; inline int calc_diff(int x, int y) { int diff = abs(x - y); return min(diff, mod - diff); } 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]; 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 max_diff = 0; for(int i = N - 1; i >= 0; i--) { for(int j = 0; j <= i; j++) { 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; } struct State { int score; int nxt_diff; vector<int> a; State(vector<int> &a, int score) : score(score), a(a), nxt_diff(0) {} State(vector<int> &a, int score, int nxt_diff) : score(score), a(a), nxt_diff(nxt_diff) {} State() : score(0), a(0), nxt_diff(0) {} int evaluate() const { if(a.size() == N) { return score; } else { return score + nxt_diff; } } bool operator<(const State &other) const { return evaluate() < other.evaluate(); } bool operator>(const State &other) const { return evaluate() > other.evaluate(); } }; int calc_nxt_diff(vector<int> &v) { int m = v.size(); int ma = 0; rep(i, m) { int nxt = (a[m][i] + a[m][i + 1]) % mod; ma = max(ma, calc_diff(nxt, v[i])); } return ma / 100000000; } vector<State> create_next_row(vector<int> &prv, int diff, int prv_score, int cnt) { 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, -1}); } else { segs.push_back({l, 1}); segs.push_back({mod, -1}); segs.push_back({0, 1}); segs.push_back({r + 1 - 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; } if(r < mod) { segs.push_back({l, 1}); segs.push_back({r + 1, -1}); } else { segs.push_back({l, 1}); segs.push_back({mod, -1}); segs.push_back({0, 1}); segs.push_back({r + 1 - mod, -1}); } } if(i != m) { s = (mod + prv[i] - s) % mod; } } sort(segs.begin(), segs.end()); int c = 0; vector<pair<int, int>> valids; int len = 0; for(auto [v, sgn] : segs) { c += sgn; if(sgn == 1 && c == m + 1) { valids.push_back({v, -1}); len -= v; } if(sgn == -1 && c == m) { valids.back().second = v; len += v; } } if(len == 0) { return vector<State>(); } else { cnt = min(cnt, len); vector<State> rets; rep(_, cnt) { int s = 0; vector<int> ret(m + 1); int target_seg = rnd.nextInt(0, valids.size()); auto [l, r] = valids[target_seg]; int target = rnd.nextInt(l, r); int score = prv_score; rep(i, m + 1) { if(i % 2 == 0) { ret[i] = (target + s) % mod; } else { ret[i] = (mod - target + s) % mod; } if(i != m) { s = (mod + prv[i] - s) % mod; } score = max(score, calc_diff(ret[i], a[m][i])); } rets.push_back(State(ret, score, calc_nxt_diff(ret))); } return rets; } } const int BW = 45; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); input(); vector<State> states; int target = 44000000; State ans; while(timer.getTime() < 1.8) { cerr << target << endl; vector<vector<State>> st(N); rep(_, 30) { int x = rnd.nextInt(0, mod); while(calc_diff(x, a[0][0]) > target) { x = rnd.nextInt(0, mod); } vector<int> v = {x}; st[0].push_back(State(v, calc_diff(x, a[0][0]))); } int idx = 0; bool success = true; while(1) { if(timer.getTime() > 1.8) { success = false; break; } while(idx >= 0 && st[idx].size() == 0) { --idx; } cout << idx << " " << st[idx].size() << endl; if(idx == -1) { success = false; break; } auto state = st[idx].back(); st[idx].pop_back(); auto nxts = create_next_row(state.a, target, state.score, BW); if(nxts.size() > 0) { if(idx == N - 2) { for(auto nxt : nxts) { if(nxt.score < ans.score || ans.score == 0) { ans = nxt; } } break; } else { for(auto nxt : nxts) { st[idx + 1].push_back(nxt); } idx++; } } else { continue; } } if(success) { target = ans.score - 2e5; } else { target += 1e5; } } cerr << ans.score << endl; output(ans.a); return 0; }