結果

問題 No.919 You Are A Project Manager
ユーザー gyouzasushigyouzasushi
提出日時 2022-03-03 07:54:02
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
TLE  
実行時間 -
コード長 6,984 bytes
コンパイル時間 2,887 ms
コンパイル使用メモリ 236,920 KB
実行使用メモリ 12,048 KB
最終ジャッジ日時 2024-07-17 04:35:55
合計ジャッジ時間 77,844 ms
ジャッジサーバーID
(参考情報)
judge5 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 TLE -
testcase_01 AC 2 ms
6,940 KB
testcase_02 AC 2 ms
6,944 KB
testcase_03 AC 2 ms
6,944 KB
testcase_04 AC 287 ms
6,944 KB
testcase_05 AC 333 ms
6,944 KB
testcase_06 AC 11 ms
6,940 KB
testcase_07 AC 859 ms
6,944 KB
testcase_08 AC 109 ms
6,940 KB
testcase_09 AC 67 ms
6,940 KB
testcase_10 AC 155 ms
6,944 KB
testcase_11 AC 141 ms
6,940 KB
testcase_12 AC 3 ms
6,944 KB
testcase_13 AC 214 ms
6,940 KB
testcase_14 AC 5 ms
6,944 KB
testcase_15 AC 38 ms
6,944 KB
testcase_16 AC 352 ms
6,940 KB
testcase_17 AC 2,930 ms
11,940 KB
testcase_18 AC 2,933 ms
11,900 KB
testcase_19 TLE -
testcase_20 TLE -
testcase_21 TLE -
testcase_22 AC 993 ms
7,152 KB
testcase_23 AC 954 ms
7,028 KB
testcase_24 AC 1,037 ms
7,300 KB
testcase_25 AC 987 ms
7,020 KB
testcase_26 AC 2,984 ms
11,032 KB
testcase_27 AC 2,518 ms
10,124 KB
testcase_28 TLE -
testcase_29 AC 2,905 ms
11,940 KB
testcase_30 AC 2,934 ms
11,940 KB
testcase_31 AC 2,935 ms
11,980 KB
testcase_32 AC 2,901 ms
11,972 KB
testcase_33 AC 1,129 ms
7,316 KB
testcase_34 AC 1,130 ms
7,448 KB
testcase_35 TLE -
testcase_36 TLE -
testcase_37 TLE -
testcase_38 TLE -
testcase_39 AC 2 ms
6,944 KB
testcase_40 AC 41 ms
6,944 KB
testcase_41 AC 7 ms
6,940 KB
testcase_42 AC 10 ms
6,940 KB
testcase_43 AC 18 ms
6,940 KB
testcase_44 AC 60 ms
6,944 KB
testcase_45 AC 10 ms
6,944 KB
testcase_46 AC 46 ms
6,940 KB
testcase_47 AC 992 ms
7,024 KB
testcase_48 AC 974 ms
7,024 KB
testcase_49 AC 1,057 ms
7,376 KB
testcase_50 AC 975 ms
7,024 KB
testcase_51 AC 859 ms
6,948 KB
testcase_52 AC 598 ms
6,940 KB
testcase_53 AC 854 ms
6,940 KB
testcase_54 AC 40 ms
6,940 KB
testcase_55 AC 1 ms
6,944 KB
testcase_56 AC 2 ms
6,944 KB
testcase_57 AC 2 ms
6,944 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
#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) (x).begin(), (x).end()
#define sz(x) int(x.size())
using namespace std;
using ll = long long;
const int INF = 1e9;
const ll LINF = 1e18;
template <class T>
bool chmax(T &a, const T &b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T>
bool chmin(T &a, const T &b) {
    if (b < a) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T>
vector<T> make_vec(size_t a) {
    return vector<T>(a);
}
template <class T, class... Ts>
auto make_vec(size_t a, Ts... ts) {
    return vector<decltype(make_vec<T>(ts...))>(a, make_vec<T>(ts...));
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
    for (int i = 0; i < int(v.size()); i++) {
        is >> v[i];
    }
    return is;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
    for (int i = 0; i < int(v.size()); i++) {
        os << v[i];
        if (i < int(v.size()) - 1) os << ' ';
    }
    return os;
}
// すでに追加したものを削除できるslope trick
// Query query(): Query{lx,rx,min_f}を返す,[lx,rx]でmin_fを取る
// add_all(T a): f(x)にaを加算する
// add_a_minus_x(T a): f(x)にmax(a-x,0)を加算する, \_
// add_x_minus_a(T a): f(x)にmax(x-a,0)を加算する, _/
// add_abs(T a): f(x)に|x-a|を加算する, \/
// erase_a_minus_x(T a): f(x)からmax(a-x,0)を削除する, \_
// erase_x_minus_a(T a): f(x)からmax(x-a,0)を削除する, _/
// erase_abs(T a): f(x)から|x-a|を削除する, \/
// clear_right(): f(x)<-min(f(t)),t<=x , \_/ -> \_
// clear_left(): f(x)<-min(f(t)),x<=t , \_/ -> _/
// shift(T a,T b): f(x)<-min(f(t)),x-b<=t<=x-a
// shift(T a): f(x)<-f(x-a),shift(a,a)してるだけ
// get(T x): f(x)を返す, fを破壊しO(sz(L)+sz(R))
// merge(SlopeTrick x): f(x)にg(x)を加算する, gを破壊する
// 中央値管理に使用したい時はadd_abs(a)していってlxなりrxなりを取ればよい

template <typename T>
struct ErasableSlopeTrick {
    const T INF = numeric_limits<T>::max() / 3;

    multiset<T> MS_l, MS_r;
    T min_f, offset_l, offset_r;

private:
    void insert_R(const T &a) {
        MS_r.insert(a - offset_r);
    }

    T top_R() const {
        if (MS_r.empty())
            return INF;
        else
            return *MS_r.begin() + offset_r;
    }

    T pop_R() {
        T val = top_R();
        if (!MS_r.empty()) MS_r.erase(MS_r.find(val - offset_r));
        return val;
    }

    void insert_L(const T &a) {
        MS_l.insert(a - offset_l);
    }

    T top_L() const {
        if (MS_l.empty())
            return -INF;
        else
            return *--MS_l.end() + offset_l;
    }

    T pop_L() {
        T val = top_L();
        if (!MS_l.empty()) MS_l.erase(MS_l.find(val - offset_l));
        return val;
    }

    size_t size() {
        return MS_l.size() + MS_r.size();
    }

public:
    ErasableSlopeTrick() : min_f(0), offset_l(0), offset_r(0) {
    }

    struct Query {
        T lx, rx, min_f;
    };

    Query query() const {
        return (Query){top_L(), top_R(), min_f};
    }

    void add_all(const T &a) {
        min_f += a;
    }

    void add_a_minus_x(const T &a) {
        insert_R(a);
        insert_L(pop_R());
        min_f += max(T(0), a - top_L());
    }

    void add_x_minus_a(const T &a) {
        insert_L(a);
        insert_R(pop_L());
        min_f += max(T(0), top_R() - a);
    }

    void add_abs(const T &a) {
        add_a_minus_x(a);
        add_x_minus_a(a);
    }

    void erase_a_minus_x(const T &a) {
        if (MS_l.find(a - offset_l) == MS_l.end()) {
            MS_r.erase(MS_r.find(a - offset_r));
            insert_R(pop_L());
        } else {
            MS_l.erase(MS_l.find(a - offset_l));
        }
        min_f -= max(T(0), a - top_R());
    }

    void erase_x_minus_a(const T &a) {
        if (MS_l.find(a - offset_l) == MS_l.end()) {
            MS_r.erase(MS_r.find(a - offset_r));
        } else {
            MS_l.erase(MS_l.find(a - offset_l));
            insert_L(pop_R());
        }
        min_f -= max(T(0), top_L() - a);
    }

    void erase_abs(const T &a) {
        erase_a_minus_x(a);
        erase_x_minus_a(a);
    }

    void clear_right() {
        if (!MS_r.empty()) MS_r.clear();
    }

    void clear_left() {
        if (!MS_l.empty()) MS_l.clear();
    }

    void shift(const T &a, const T &b) {
        assert(a <= b);
        offset_l += a;
        offset_r += b;
    }

    void shift(const T &a) {
        shift(a, a);
    }

    T get(const T &x) {
        T ret = min_f;
        while (!MS_l.empty()) ret += max(T(0), pop_L() - x);
        while (!MS_r.empty()) ret += max(T(0), x - pop_R());
        return ret;
    }

    void merge(ErasableSlopeTrick &st) {
        if (st.size() > size()) {
            swap(st.MS_l, MS_l);
            swap(st.MS_r, MS_r);
            swap(st.min_f, min_f);
            swap(st.offset_l, offset_l);
            swap(st.offset_r, offset_r);
        }
        while (!st.MS_r.empty()) add_x_minus_a(st.pop_R());
        while (!st.MS_l.empty()) add_a_minus_x(st.pop_L());
        min_f += st.min_f;
    }
};
int main() {
    int n;
    cin >> n;
    vector<ll> a(n);
    cin >> a;

    vector<pair<int, int>> qs;
    for (int k = 1; k <= n; k++) {
        for (int l = 0, r = k; r <= n; l += k, r += k) {
            qs.emplace_back(l, r);
        }
    }
    const int m = sqrt(sz(qs));
    sort(all(qs), [&](auto a, auto b) {
        auto [la, ra] = a;
        auto [lb, rb] = b;
        if (la / m != lb / m) return la / m < lb / m;
        return (la / m & 1) ? ra > rb : ra < rb;
    });

    vector maxs(2, vector<vector<ll>>(n + 1));
    rep(i, 2) {
        int l = 0, r = 0;
        ErasableSlopeTrick<ll> est;
        vector<unordered_map<ll, ll>> meds(n + 1);
        for (auto [nl, nr] : qs) {
            while (l > nl) {
                --l;
                est.add_abs(a[l]);
            }
            while (r < nr) {
                est.add_abs(a[r]);
                r++;
            }
            while (l < nl) {
                est.erase_abs(a[l]);
                l++;
            }
            while (r > nr) {
                --r;
                est.erase_abs(a[r]);
            }
            meds[nl][nr] = est.query().lx;
        }

        for (int k = 1; k <= n; k++) {
            ll mx = 0, sm = 0;
            maxs[i][k] = {0};
            for (int l = 0, r = k; r <= n; l += k, r += k) {
                chmax(mx, sm + meds[l][r]);
                sm += meds[l][r];
                maxs[i][k].push_back(mx);
            }
        }

        reverse(all(a));
    }

    ll ans = 0;
    for (ll k = 1; k <= n; k++) {
        int x = sz(maxs[0][k]);
        for (int i = 0; i < x; i++) {
            chmax(ans, k * (maxs[0][k][i] + maxs[1][k][x - 1 - i]));
        }
    }
    cout << ans << '\n';
}
0