結果
| 問題 |
No.2988 Min-Plus Convolution Query
|
| コンテスト | |
| ユーザー |
Kude
|
| 提出日時 | 2024-12-13 01:40:29 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 4,119 bytes |
| コンパイル時間 | 4,656 ms |
| コンパイル使用メモリ | 277,192 KB |
| 実行使用メモリ | 40,236 KB |
| 最終ジャッジ日時 | 2024-12-13 01:41:41 |
| 合計ジャッジ時間 | 67,992 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 20 TLE * 20 |
ソースコード
#include<bits/stdc++.h>
namespace {
#pragma GCC diagnostic ignored "-Wunused-function"
#include<atcoder/all>
#pragma GCC diagnostic warning "-Wunused-function"
using namespace std;
using namespace atcoder;
#define rep(i,n) for(int i = 0; i < (int)(n); i++)
#define rrep(i,n) for(int i = (int)(n) - 1; i >= 0; i--)
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
template<class T> bool chmax(T& a, const T& b) { if (a < b) { a = b; return true; } else return false; }
template<class T> bool chmin(T& a, const T& b) { if (b < a) { a = b; return true; } else return false; }
using ll = long long;
// using P = pair<int,int>;
using VI = vector<int>;
using VVI = vector<VI>;
using VL = vector<ll>;
using VVL = vector<VL>;
constexpr int INF = 1001001001;
constexpr int M = 200010;
constexpr int B = 3125;
int a[M], b[M];
int ans_memo[2 * M];
bool invalid[M];
int n;
// https://noshi91.github.io/Library/algorithm/smawk.cpp.html
#line 2 "other/int_alias.cpp"
#include <cstddef>
#include <cstdint>
using i32 = std::int32_t;
using i64 = std::int64_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;
using isize = std::ptrdiff_t;
using usize = std::size_t;
#line 2 "algorithm/smawk.cpp"
#include <functional>
#include <numeric>
#include <vector>
template <class Select>
std::vector<usize> smawk(const usize row_size, const usize col_size,
const Select &select) {
using vec_zu = std::vector<usize>;
const std::function<vec_zu(const vec_zu &, const vec_zu &)> solve =
[&](const vec_zu &row, const vec_zu &col) -> vec_zu {
const usize n = row.size();
if (n == 0)
return {};
vec_zu c2;
for (const usize i : col) {
while (!c2.empty() && select(row[c2.size() - 1], c2.back(), i))
c2.pop_back();
if (c2.size() < n)
c2.push_back(i);
}
vec_zu r2;
for (usize i = 1; i < n; i += 2)
r2.push_back(row[i]);
const vec_zu a2 = solve(r2, c2);
vec_zu ans(n);
for (usize i = 0; i != a2.size(); i += 1)
ans[i * 2 + 1] = a2[i];
usize j = 0;
for (usize i = 0; i < n; i += 2) {
ans[i] = c2[j];
const usize end = i + 1 == n ? c2.back() : ans[i + 1];
while (c2[j] != end) {
j += 1;
if (select(row[i], ans[i], c2[j]))
ans[i] = c2[j];
}
}
return ans;
};
vec_zu row(row_size);
std::iota(row.begin(), row.end(), 0);
vec_zu col(col_size);
std::iota(col.begin(), col.end(), 0);
return solve(row, col);
}
/**
* @brief SMAWK Algorithm
* @docs docs/smawk.md
*/
void dfs(int l_ask, int r_ask, int l_a, int r_a) {
if (l_ask == r_ask) return;
int c_ask = (l_ask + r_ask) / 2;
int mn = 2 * INF;
int imn = max(l_a, c_ask - (n - 1));
for (int ia = imn, iar = min({r_a, n, c_ask + 1}); ia < iar; ia++) {
if (!invalid[ia] && chmin(mn, a[ia] + b[c_ask - ia])) imn = ia;
}
ans_memo[c_ask] = mn;
dfs(l_ask, c_ask, l_a, imn + 1);
dfs(c_ask + 1, r_ask, imn, r_a);
}
int P[M], X[M], K[M];
} int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int q;
cin >> n >> q;
rep(i, n) cin >> a[i];
rep(i, n) cin >> b[i];
rep(i, q) cin >> P[i] >> X[i] >> K[i], P[i]--, K[i] -= 2;
int bl = 0, br = 0;
rep(iq, q) {
if (iq % B == 0) {
bl = iq;
br = min(iq + B, q);
for (int i = bl; i < br; i++) invalid[P[i]] = true;
auto choice = smawk(2 * n - 1, n, [](int i, int j, int k) {
int bj = i - j, bk = i - k;
if (bj >= n) return true;
if (bk < 0) return false;
if (invalid[j]) return true;
if (invalid[k]) return false;
return a[j] + b[bj] > a[k] + b[bk];
});
rep(i, 2 * n - 1) {
int j = choice[i], bj = i - j;
ans_memo[i] = 0 <= bj && bj < n && !invalid[j] ? a[j] + b[bj] : 2 * INF;
}
// dfs(0, 2 * n - 1, 0, n);
for (int i = bl; i < br; i++) invalid[P[i]] = false;
}
a[P[iq]] = X[iq];
int ans = ans_memo[K[iq]];
for (int i = bl; i < br; i++) {
int ia = P[i], ib = K[iq] - ia;
if (0 <= ib && ib < n) chmin(ans, a[ia] + b[ib]);
}
cout << ans << '\n';
}
}
Kude