답안 #960312

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
960312 2024-04-10T08:38:42 Z alextodoran 별자리 3 (JOI20_constellation3) C++17
0 / 100
5 ms 20828 KB
/**
 _  _   __  _ _ _  _  _ _
 |a  ||t  ||o    d | |o  |
| __    _| | _ | __|  _ |
| __ |/_  | __  /__\ / _\|

**/

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N_MAX = 200000;
const int M_MAX = 200000;
const int LOG_N = 18;

int N;
int A[N_MAX + 2];
int M;
struct Star {
    int x, y;
    int cost;
};
Star S[N_MAX + 2];

int L[N_MAX + 2], R[N_MAX + 2];

int st[N_MAX + 2], cnt;
void get_LR () {
    cnt = 0; st[0] = 0;
    for (int i = 1; i <= N; i++) {
        while (cnt > 0 && A[i] >= A[st[cnt]]) {
            cnt--;
        }
        L[i] = st[cnt] + 1;
        st[++cnt] = i;
    }
    cnt = 0; st[0] = N + 1;
    for (int i = N; i >= 1; i--) {
        while (cnt > 0 && A[i] >= A[st[cnt]]) {
            cnt--;
        }
        R[i] = st[cnt] - 1;
        st[++cnt] = i;
    }
}

int node[N_MAX + 2];
int parent[N_MAX + 2];
vector <int> sons[N_MAX + 2];
int anc[N_MAX + 2][LOG_N];
int root;

vector <int> stars[N_MAX + 2];

void get_tree () {
    iota(node + 1, node + N + 1, 1);
    for (int i = 1; i <= N; i++) {
        int l = L[i] - 1, r = R[i] + 1;
        if (1 <= l && r <= N && A[l] == A[r]) {
            node[r] = node[l];
        }
        if (A[i] == A[i - 1]) {
            node[i] = node[i - 1];
        }
    }
    for (int i = 1; i <= N; i++) {
        int l = L[i] - 1, r = R[i] + 1;
        parent[node[i]] = (A[l] <= A[r] ? node[l] : node[r]);
    }
    for (int u = 1; u <= N; u++) {
        if (node[u] == u) {
            sons[parent[u]].push_back(u);
            anc[u][0] = parent[u];
            if (parent[u] == 0) {
                root = u;
            }
        }
    }
    for (int k = 1; k < LOG_N; k++) {
        for (int u = 1; u <= N; u++) {
            anc[u][k] = anc[anc[u][k - 1]][k - 1];
        }
    }
    for (int i = 1; i <= M; i++) {
        int u = S[i].x;
        for (int k = LOG_N - 1; k >= 0; k--) {
            if (A[anc[u][k]] < S[i].y) {
                u = anc[u][k];
            }
        }
        stars[u].push_back(i);
    }
}

int eul[N_MAX + 2], eur[N_MAX + 2];
int curr;

void dfs (int u) {
    eul[u] = ++curr;
    for (int v : sons[u]) {
        dfs(v);
    }
    eur[u] = curr;
}

ll max_keep[N_MAX + 2];
ll sum_up[N_MAX + 2];
ll sum_sons_up[N_MAX + 2];

void update (ll Fen[], int pos, ll val) {
    for (int i = pos; i <= N; i += i & -i) {
        Fen[i] += val;
    }
}
void update (ll Fen[], int l, int r, ll val) {
    update(Fen, l, val);
    update(Fen, r + 1, -val);
}
ll query (ll Fen[], int pos) {
    ll sum = 0;
    for (int i = pos; i >= 1; i -= i & -i) {
        sum += Fen[i];
    }
    return sum;
}

ll chain_sum (int u) {
    return query(sum_sons_up, eul[u]) - query(sum_up, eul[u]);
}

void solve (int u) {
    ll sum_sons = 0;
    for (int v : sons[u]) {
        solve(v);
        sum_sons += max_keep[v];
    }
    update(sum_sons_up, eul[u], eur[u], sum_sons);
    max_keep[u] = sum_sons;
    for (int i : stars[u]) {
        max_keep[u] = max(max_keep[u], S[i].cost + chain_sum(node[S[i].x]));
    }
    update(sum_up, eul[u], eur[u], max_keep[u]);
}

int main () {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> N;
    for (int x = 1; x <= N; x++) {
        cin >> A[x];
    }
    A[0] = A[N + 1] = N + 1;
    cin >> M;
    for (int i = 1; i <= M; i++) {
        cin >> S[i].x >> S[i].y >> S[i].cost;
    }
    get_LR();
    get_tree();
    dfs(root);
    solve(root);
    ll answer = 0;
    for (int i = 1; i <= M; i++) {
        answer += S[i].cost;
    }
    answer -= max_keep[root];
    cout << answer << "\n";

    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Incorrect 5 ms 20828 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 5 ms 20828 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 5 ms 20828 KB Output isn't correct
2 Halted 0 ms 0 KB -