제출 #1307026

#제출 시각아이디문제언어결과실행 시간메모리
1307026succe_edNile (IOI24_nile)C++20
0 / 100
129 ms34908 KiB
#include <vector>
#include <algorithm>
#include "nile.h"

using namespace std;

const long long INF = 1e18;

struct Matrix {
    long long m[3][3];
    Matrix() {
        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                m[i][j] = INF;
    }
};

struct Artifact {
    int w, a, b;
};

Matrix merge(const Matrix& A, const Matrix& B) {
    Matrix C;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            for (int k = 0; k < 3; k++) {
                // Combine ranges such that the total number of items 
                // used across the boundary maintains the correct offset.
                C.m[i][j] = min(C.m[i][j], A.m[i][k] + B.m[k][j]);
            }
        }
    }
    return C;
}

int SZ;
Matrix tree[400005];
bool can_pair2[100005], can_pair3[100005];
Artifact sorted_arts[100005];

void update_node(int v, int idx) {
    tree[v] = Matrix();
    // Case 1: Send artifact alone (Cost A)
    tree[v].m[0][1] = sorted_arts[idx].a;
    tree[v].m[1][2] = sorted_arts[idx].a;
    tree[v].m[2][0] = sorted_arts[idx].a;

    // Case 2: Send in a pair (Cost B)
    // Offset logic handles the parity of pairs
    if (can_pair2[idx]) {
        tree[v].m[0][2] = min(tree[v].m[0][2], (long long)sorted_arts[idx].b + sorted_arts[idx - 1].b);
        tree[v].m[1][0] = min(tree[v].m[1][0], (long long)sorted_arts[idx].b + sorted_arts[idx - 1].b);
        tree[v].m[2][1] = min(tree[v].m[2][1], (long long)sorted_arts[idx].b + sorted_arts[idx - 1].b);
    }
    
    // Case 3: Skip one (triple range)
    if (can_pair3[idx]) {
        tree[v].m[0][0] = min(tree[v].m[0][0], (long long)sorted_arts[idx].b + sorted_arts[idx - 2].b + sorted_arts[idx - 1].a);
        tree[v].m[1][1] = min(tree[v].m[1][1], (long long)sorted_arts[idx].b + sorted_arts[idx - 2].b + sorted_arts[idx - 1].a);
        tree[v].m[2][2] = min(tree[v].m[2][2], (long long)sorted_arts[idx].b + sorted_arts[idx - 2].b + sorted_arts[idx - 1].a);
    }
}

void build(int v, int tl, int tr) {
    if (tl == tr) {
        update_node(v, tl);
    } else {
        int tm = (tl + tr) / 2;
        build(2 * v, tl, tm);
        build(2 * v + 1, tm + 1, tr);
        tree[v] = merge(tree[2 * v], tree[2 * v + 1]);
    }
}

void update(int v, int tl, int tr, int pos) {
    if (tl == tr) {
        update_node(v, tl);
    } else {
        int tm = (tl + tr) / 2;
        if (pos <= tm) update(2 * v, tl, tm, pos);
        else update(2 * v + 1, tm + 1, tr, pos);
        tree[v] = merge(tree[2 * v], tree[2 * v + 1]);
    }
}

vector<long long> calculate_costs(vector<int> W, vector<int> A, vector<int> B, vector<int> E) {
    int n = W.size();
    vector<pair<int, int>> temp(n);
    for (int i = 0; i < n; i++) temp[i] = {W[i], i};
    sort(temp.begin(), temp.end());

    for (int i = 0; i < n; i++) {
        sorted_arts[i] = {W[temp[i].second], A[temp[i].second], B[temp[i].second]};
    }

    vector<pair<int, int>> edges;
    for (int i = 1; i < n; i++) edges.push_back({sorted_arts[i].w - sorted_arts[i - 1].w, i});
    for (int i = 2; i < n; i++) edges.push_back({sorted_arts[i].w - sorted_arts[i - 2].w, i + n});
    sort(edges.begin(), edges.end());

    int q = E.size();
    vector<pair<int, int>> queries(q);
    for (int i = 0; i < q; i++) queries[i] = {E[i], i};
    sort(queries.begin(), queries.end());

    build(1, 0, n - 1);

    vector<long long> results(q);
    int ptr = 0;
    for (int i = 0; i < q; i++) {
        while (ptr < edges.size() && edges[ptr].first <= queries[i].first) {
            int val = edges[ptr].second;
            if (val < n) {
                can_pair2[val] = true;
                update(1, 0, n - 1, val);
            } else {
                can_pair3[val - n] = true;
                update(1, 0, n - 1, val - n);
            }
            ptr++;
        }
        results[queries[i].second] = tree[1].m[0][n % 3];
    }

    return 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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...