Submission #1315734

#TimeUsernameProblemLanguageResultExecution timeMemory
1315734abcd123456Bulldozer (JOI17_bulldozer)C++20
60 / 100
2099 ms66524 KiB
#include <bits/stdc++.h>
#define ll long long
#define itachi ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define maxn 2005
#define int long long

using namespace std;

const long double PI = acosl(-1.0L);
const long double EPS = 1e-18L;

int n;
int X[maxn], Y[maxn], W[maxn];

struct Node {
    int sum, pre, suf, best;
    Node(int v = 0) {
        sum = v;
        pre = suf = best = max(0LL, v);
    }
};

Node st[4 * maxn];

Node combine(const Node &L, const Node &R) {
    Node res;
    res.sum = L.sum + R.sum;
    res.pre = max(L.pre, L.sum + R.pre);
    res.suf = max(R.suf, R.sum + L.suf);
    res.best = max({L.best, R.best, L.suf + R.pre});
    return res;
}

void build(int id, int l, int r, const vector<int> &arr) {
    if (l == r) {
        st[id] = Node(arr[l]);
        return;
    }
    int mid = (l + r) >> 1;
    build(id << 1, l, mid, arr);
    build(id << 1 | 1, mid + 1, r, arr);
    st[id] = combine(st[id << 1], st[id << 1 | 1]);
}

void update(int id, int l, int r, int pos, int val) {
    if (l == r) {
        st[id] = Node(val);
        return;
    }
    int mid = (l + r) >> 1;
    if (pos <= mid) update(id << 1, l, mid, pos, val);
    else update(id << 1 | 1, mid + 1, r, pos, val);
    st[id] = combine(st[id << 1], st[id << 1 | 1]);
}

struct Event {
    long double ang;
    int u, v;
    bool operator < (const Event &other) const {
        if (fabsl(ang - other.ang) > EPS) return ang < other.ang;
        if (u != other.u) return u < other.u;
        return v < other.v;
    }
};

signed main() {
    itachi
    cin>>n;
    for (int i = 1; i <= n; i++) {
        cin >> X[i] >> Y[i] >> W[i];
    }

    vector<Event> events;
    for (int i = 1; i <= n; i++) {
        for (int j = i + 1; j <= n; j++) {
            long double dx = X[j] - X[i];
            long double dy = Y[j] - Y[i];
            long double ang = atan2l(dy, dx);
            if (ang < 0) ang += PI;
            if (ang >= PI - EPS) ang -= PI;
            events.push_back({ang, i, j});
        }
    }
    sort(events.begin(), events.end());

    vector<int> ord(n + 1);
    for (int i = 1; i <= n; i++) ord[i] = i;

    sort(ord.begin() + 1, ord.end(), [&](int a, int b) {
        if (fabsl(Y[a] - Y[b]) > 1e-18) return Y[a] < Y[b];
        return X[a] < X[b];
    });

    vector<int> pos(n + 1);
    vector<int> initial_w(n + 1);
    for (int i = 1; i <= n; i++) {
        pos[ord[i]] = i;
        initial_w[i] = W[ord[i]];
    }

    build(1, 1, n, initial_w);
    int ans = st[1].best;

    for (int i = 0; i < (int)events.size(); ) {
        int j = i;
        while (j < (int)events.size() && fabsl(events[j].ang - events[i].ang) < EPS) {
            j++;
        }

        int L = n + 1, R = 0;
        for (int k = i; k < j; k++) {
            L = min({L, pos[events[k].u], pos[events[k].v]});
            R = max({R, pos[events[k].u], pos[events[k].v]});
        }

        reverse(ord.begin() + L, ord.begin() + R + 1);
        for (int k = L; k <= R; k++) {
            pos[ord[k]] = k;
            update(1, 1, n, k, W[ord[k]]);
        }

        ans = max(ans, st[1].best);
        i = j;
    }

    cout << ans << endl;
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...