Submission #347380

#TimeUsernameProblemLanguageResultExecution timeMemory
347380markthitrinSalesman (IOI09_salesman)C++14
60 / 100
1428 ms47596 KiB
#include <iostream> #include <vector> #include <queue> #include <algorithm> long long max_range = 500001; class name { public: long long value; long long pos; long long time; bool operator<(const name b) const { if (time != b.time) return time < b.time; return pos < b.pos; } }; long long dpleft[500005]; // let data 0 be the wosrt; long long dpright[500005]; long long segleft[1100000]; long long segright[1100000]; name a[500005]; long long dp[500005];// actual value; long long N, U, D, S; // U for left , D for right; void change(long long* seg, long long* data, long long pos, long long number, long long left = 1, long long right = max_range, long long i = 1) { if (left == right) { data[pos] = number; seg[i] = pos; return; } long long mid = (right + left) / 2; if (pos <= mid) { change(seg, data, pos, number, left, mid, 2 * i); seg[i] = seg[2 * i + 1]; if (data[seg[2 * i]] > data[seg[i]]) seg[i] = seg[2 * i]; return; } else { change(seg, data, pos, number, mid + 1, right, 2 * i + 1); seg[i] = seg[2 * i]; if (data[seg[2 * i + 1]] > data[seg[i]]) seg[i] = seg[2 * i + 1]; return; } } long long get_max(long long* seg, long long* data, long long s, long long e, long long left = 1, long long right = max_range, long long i = 1) { if (left >= s && right <= e) return seg[i]; else if (left > e || right < s) return 0; long long mid = (right + left) / 2; long long get1, get2; get1 = get_max(seg, data, s, e, left, mid, 2 * i); get2 = get_max(seg, data, s, e, mid + 1, right, 2 * i + 1); if (data[get1] > data[get2]) return get1; return get2; } void set_up(long long* seg, long long* data, long long left = 1, long long right = max_range, long long i = 1) { if (left == right) { seg[i] = left; return; } long long mid = (right + left) / 2; set_up(seg, data, left, mid, 2 * i); set_up(seg, data, mid + 1, right, 2 * i + 1); if (data[seg[2 * i]] > data[seg[2 * i + 1]]) seg[i] = seg[2 * i]; else seg[i] = seg[2 * i + 1]; } void func(long long start, long long end) { if (end - start == 1) { long long max = dp[a[start].pos]; long long get_pos_right = get_max(segright, dpright, 1, a[start].pos - 1); long long get_pos_left = get_max(segleft, dpleft, a[start].pos + 1, max_range); max = std::max(max, dp[get_pos_right] - std::abs(a[start].pos - get_pos_right) * D); max = std::max(max, dp[get_pos_left] - std::abs(a[start].pos - get_pos_left) * U); //std::cout << "get pos : " << get_pos_right << " " << get_pos_left << "\n"; dp[a[start].pos] = max + a[start].value; change(segright, dpright, a[start].pos, dp[a[start].pos] - (max_range - a[start].pos) * D); change(segleft, dpleft, a[start].pos, dp[a[start].pos] - a[start].pos * U); } else { // has finished } } int main() { std::cin.sync_with_stdio(false); std::cin.tie(0); std::cin >> N >> U >> D >> S; for (long long q = 0; q < N; q++) { std::cin >> a[q].time >> a[q].pos >> a[q].value; } // set up std::sort(a, a + N); dpright[0] = -100000000000; dpleft[0] = -100000000000; dp[0] = -100000000000; for (long long q = 1; q <= max_range; q++) { if (q < S) { dp[q] = std::abs(q - S) * -U; } else if (q > S) { dp[q] = std::abs(q - S) * -D; } } for (long long q = 1; q <= max_range; q++) { dpleft[q] = dp[q] - q * U; dpright[q] = dp[q] - (max_range - q) * D; } set_up(segleft, dpleft); set_up(segright, dpright); // dinamic programming; long long start = 0; long long end = 0; while (end != N) { while (a[end].time == a[start].time) ++end; func(start, end); start = end; } long long the_result = dp[S]; for (long long q = 1; q <= max_range; q++) { if (q < S) { the_result = std::max(the_result, dp[q] - D * std::abs(q - S)); } else { the_result = std::max(the_result, dp[q] - U * std::abs(q - S)); } } std::cout << the_result; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...