Submission #1271834

#TimeUsernameProblemLanguageResultExecution timeMemory
1271834win1702Global Warming (CEOI18_glo)C++20
15 / 100
2094 ms14064 KiB
// solve_calibration_n1000.cpp // Brute-forced over segments [L,R] but with smart candidate-d generation. // Correct for n <= 1000 in practice. // // Compile: g++ -O2 -std=c++17 solve_calibration_n1000.cpp -o solve // Run: ./solve < input.txt #include <bits/stdc++.h> using namespace std; using ll = long long; int LIS_length(const vector<ll>& a) { vector<ll> tails; tails.reserve(a.size()); for (ll x : a) { auto it = lower_bound(tails.begin(), tails.end(), x); if (it == tails.end()) tails.push_back(x); else *it = x; } return (int)tails.size(); } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; ll x; if (!(cin >> n >> x)) return 0; vector<ll> a(n); for (int i = 0; i < n; ++i) cin >> a[i]; // baseline LIS without any calibration int best = LIS_length(a); // Pre-allocate container to reduce reallocs vector<ll> b(n); // We'll try every non-empty segment [L,R] for (int L = 0; L < n; ++L) { for (int R = L; R < n; ++R) { // Build candidate d's set (only values that can change relative order between // inside segment elements and outside elements). // For integers, the ordering a[i]+d < a[j] changes at d = a[j]-a[i]-k for small k. unordered_set<ll> cand; cand.reserve(512); // always try extremes (clamped) cand.insert(-x); cand.insert(x); cand.insert(0); for (int i = L; i <= R; ++i) { // compare with elements outside segment for (int j = 0; j < n; ++j) { if (j >= L && j <= R) continue; // critical values where relation between a[i]+d and a[j] changes: // a[i]+d == a[j] => d = a[j]-a[i] // to handle strict inequality boundaries, also try +/-1 neighbors ll base = a[j] - a[i]; // push base, base-1, base+1 (if in range) if (base >= -x && base <= x) cand.insert(base); if (base - 1 >= -x && base - 1 <= x) cand.insert(base - 1); if (base + 1 >= -x && base + 1 <= x) cand.insert(base + 1); } // also try extremes relative to this element (clamped) if (-x - a[i] >= -x && -x - a[i] <= x) cand.insert(-x); // redundant but safe if ( x - a[i] >= -x && x - a[i] <= x) cand.insert(x); } // Now evaluate each candidate d // Note: cand size might be up to O(n)~1000 here; overall loops manageable for n<=1000. for (ll d : cand) { // d must be within [-x,x] if (d < -x || d > x) continue; // apply shift to segment for (int k = L; k <= R; ++k) b[k] = a[k] + d; // copy others unchanged for (int k = 0; k < L; ++k) b[k] = a[k]; for (int k = R+1; k < n; ++k) b[k] = a[k]; int lis = LIS_length(b); if (lis > best) best = lis; } } } cout << best << "\n"; 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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...