結果

問題 No.2488 Mod Sum Maximization
ユーザー sotanishy
提出日時 2023-09-29 23:59:36
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 572 ms / 2,000 ms
コード長 3,558 bytes
コンパイル時間 1,896 ms
コンパイル使用メモリ 200,596 KB
最終ジャッジ日時 2025-02-17 03:41:38
ジャッジサーバーID
(参考情報)
judge2 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 38
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T>
bool chmax(T& a, const T& b) {
return a < b ? (a = b, 1) : 0;
}
template <typename T>
bool chmin(T& a, const T& b) {
return a > b ? (a = b, 1) : 0;
}
template <typename M>
class SegmentTree {
using T = typename M::T;
public:
SegmentTree() = default;
explicit SegmentTree(int n) : SegmentTree(std::vector<T>(n, M::id())) {}
explicit SegmentTree(const std::vector<T>& v) {
size = 1;
while (size < (int)v.size()) size <<= 1;
node.resize(2 * size, M::id());
std::copy(v.begin(), v.end(), node.begin() + size);
for (int i = size - 1; i > 0; --i)
node[i] = M::op(node[2 * i], node[2 * i + 1]);
}
T operator[](int k) const { return node[k + size]; }
void update(int k, const T& x) {
k += size;
node[k] = x;
while (k >>= 1) node[k] = M::op(node[2 * k], node[2 * k + 1]);
}
T fold(int l, int r) const {
T vl = M::id(), vr = M::id();
for (l += size, r += size; l < r; l >>= 1, r >>= 1) {
if (l & 1) vl = M::op(vl, node[l++]);
if (r & 1) vr = M::op(node[--r], vr);
}
return M::op(vl, vr);
}
template <typename F>
int find_first(int l, F cond) const {
T v = M::id();
for (l += size; l > 0; l >>= 1) {
if (l & 1) {
T nv = M::op(v, node[l]);
if (cond(nv)) {
while (l < size) {
nv = M::op(v, node[2 * l]);
if (cond(nv))
l = 2 * l;
else
v = nv, l = 2 * l + 1;
}
return l + 1 - size;
}
v = nv;
++l;
}
}
return -1;
}
template <typename F>
int find_last(int r, F cond) const {
T v = M::id();
for (r += size; r > 0; r >>= 1) {
if (r & 1) {
--r;
T nv = M::op(node[r], v);
if (cond(nv)) {
while (r < size) {
nv = M::op(node[2 * r + 1], v);
if (cond(nv))
r = 2 * r + 1;
else
v = nv, r = 2 * r;
}
return r - size;
}
v = nv;
}
}
return -1;
}
private:
int size;
std::vector<T> node;
};
struct MaxMonoid {
using T = ll;
static T id() { return -1e18; }
static T op(T a, T b) { return max(a, b); }
};
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout << fixed << setprecision(15);
int N;
cin >> N;
vector<ll> A(N);
for (auto& x : A) cin >> x;
SegmentTree<MaxMonoid> st(N);
st.update(0, 0);
rep(i, 0, N) {
ll d = st.fold(i, N);
rep(n, 1, A.back() / A[i] + 2) {
int x = A[i] * n;
int k = lower_bound(all(A), x) - A.begin();
if (k > 0) {
st.update(k - 1,
max(st[k - 1], d + A[k - 1] % A[i] - A[k - 1]));
}
}
}
cout << accumulate(all(A), 0LL) + st[N - 1] << endl;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0