Submission #1181688

#TimeUsernameProblemLanguageResultExecution timeMemory
1181688sagnbaevvNile (IOI24_nile)C++20
Compilation error
0 ms0 KiB
#include <bits/stdc++.h> using namespace std; static const long long INF = 1LL<<60; int main(){ ios::sync_with_stdio(false); cin.tie(NULL); int N; cin >> N; vector<long long> W(N), A(N), B(N), save(N); for(int i=0; i<N; i++){ cin >> W[i] >> A[i] >> B[i]; save[i] = A[i] - B[i]; // How much we "save" by pairing this artifact } int Q; cin >> Q; vector<long long> E(Q); for(int i=0; i<Q; i++){ cin >> E[i]; } // We will sort artifacts by weight once. // idx[] keeps the original index after sorting by W. vector<int> idx(N); iota(idx.begin(), idx.end(), 0); sort(idx.begin(), idx.end(), [&](int p, int q){ return W[p] < W[q]; }); // Also create sorted W', save' vector<long long> Ws(N), Sv(N); for(int i=0; i<N; i++){ Ws[i] = W[idx[i]]; Sv[i] = save[idx[i]]; } // For each query D, we want to compute the maximum sum of "Sv[i]+Sv[j]" // over pairs (i,j) with i<j, Ws[j]-Ws[i] <= D, and no index used more than once. // Equivalently, we do a 1D DP: // dp[k] = maximum sum of matched-vertices' 'save' among first k artifacts (in sorted order). // Transition: // dp[k] = max of: // dp[k-1] (skip k-th artifact) // dp(t-1) + Sv[t] + Sv[k] for some t < k with Ws[k]-Ws[t] <= D // We only pick one t that maximizes dp(t-1)+Sv[t]. // We can maintain the maximum of (dp[i-1]+Sv[i]) for i in a valid range via two-pointer. // But doing this for each query in O(N) => O(NQ) can be 1e10 if N,Q=1e5, too large. // // The following code is the direct DP approach (typical for smaller subtask), // which will work fine for small or moderate N,Q but not for the largest constraints. // Precompute the sumA = sum of all A[i], which is the baseline cost if everything is alone. long long sumA = 0; for(int i=0; i<N; i++){ sumA += A[i]; } // We'll just implement the direct solution. (Will pass smaller subtasks.) for(int qi=0; qi<Q; qi++){ long long D = E[qi]; // We'll do a two-pointer DP approach: long long ans = 0; vector<long long> dp(N+1, 0LL); // bestVal will maintain the maximum of (dp[i] + Sv[i+1]) // for i in the range that satisfies Ws[current] - Ws[i+1] <= D. // We'll use a pointer 'leftPtr' to shrink/grow the valid range. long long bestVal = -INF; int leftPtr = 0; for(int k=1; k<=N; k++){ // First, drop from the leftPtr if Ws[k-1] - Ws[leftPtr] > D // so that Ws[k-1] - Ws[i] <= D for i >= leftPtr while(Ws[k-1] - Ws[leftPtr] > D){ // Before we move leftPtr up, we need to remove the contribution from index leftPtr // from bestVal if it is the one in bestVal. We'll just recompute bestVal after shift. // (Simplest approach: increment leftPtr, then recalc bestVal from scratch in O(1) // by tracking dp[i], but that can be done carefully with a data structure. // For simplicity, just do a lazy approach.) leftPtr++; } // Recompute bestVal in [leftPtr..(k-1)) as max of dp[i] + Sv[i+1] for i from 0..(k-1) // but we only want i from leftPtr..(k-1)-1 in 1-based dp index. This can be O(k-leftPtr) // leading to O(N^2) in worst case. Fine for small subtasks. // We'll keep track of bestVal by scanning that range: bestVal = -INF; for(int i=leftPtr; i<k-1; i++){ long long cand = dp[i] + Sv[i]; if(cand > bestVal) bestVal = cand; } // dp[k] = max of dp[k-1], or bestVal + Sv[k-1] dp[k] = dp[k-1]; if(bestVal != -INF){ long long possible = bestVal + Sv[k-1]; if(possible > dp[k]) dp[k] = possible; } } long long totalSaving = dp[N]; long long cost = sumA - totalSaving; cout << cost << "\n"; } return 0; }

Compilation message (stderr)

/usr/bin/ld: /tmp/ccZoMh3r.o: in function `main':
grader.cpp:(.text.startup+0x0): multiple definition of `main'; /tmp/cckiAk2O.o:nile.cpp:(.text.startup+0x0): first defined here
/usr/bin/ld: /tmp/ccZoMh3r.o: in function `main':
grader.cpp:(.text.startup+0x30e): undefined reference to `calculate_costs(std::vector<int, std::allocator<int> >, std::vector<int, std::allocator<int> >, std::vector<int, std::allocator<int> >, std::vector<int, std::allocator<int> >)'
collect2: error: ld returned 1 exit status