Submission #504134

#TimeUsernameProblemLanguageResultExecution timeMemory
504134gavgavFountain (eJOI20_fountain)C++17
100 / 100
105 ms10464 KiB
// This is Lucallie's solving but with some optimizations and explanations, 'cause when I solved this problem with own code I wondered why this solving is so fast and try to understand it, but he's code is weird and strange, but super fast. #include <bits/stdc++.h> using namespace std; struct reservoir{ int diameter; short capacity; // 1 <= diameter <= 10^9 | 1 <= capacity <= 1000 }; struct query{ int level, volume, answer; // 1 <= volume <= 10^9 }; int main() { int height, queries_number, necessary, top, i, j; // 2 <= height <= 10^5 | 1 <= queries 2 * 10^5 scanf( "%d%d", &height, &queries_number); int previous_request[queries_number + 1], // i-th number of previous_request keeps index of previous request that opened tap of this request last_request[height + 1] {}, // i-th number of last_request keeps index of last query that open tap at i-th reservoir necessary_water[height + 1], // i-th number of necessary_water keeps volume of water which need to reach waterways from i-th + 1 reservoir stream[height + 1]; reservoir reservoirs[height + 1]; query queries[queries_number + 1]; reservoirs[0].diameter = 1000000001; // maximum possible diameter + 1 reservoirs[0].capacity = 0; for (i = 1; i <= height; ++i) scanf( "%d%hd", &reservoirs[i].diameter, &reservoirs[i].capacity); for (i = 1; i <= queries_number; ++i) { scanf( "%d%d", &queries[i].level, &queries[i].volume); previous_request[i] = last_request[queries[i].level]; last_request[queries[i].level] = i; } stream[0] = 0; top = 0; necessary = 0; int left, middle, right; for (i = height; i > 0; --i) { while (reservoirs[i].diameter >= reservoirs[stream[top]].diameter) { necessary -= reservoirs[stream[top]].capacity; --top; } ++top; stream[top] = i; necessary_water[top] = necessary; necessary += reservoirs[i].capacity; j = last_request[i]; while (j != 0) { right = top + 1; left = 0; while (right - left > 1 ) { middle = (right + left) / 2; if (necessary - necessary_water[middle] >= queries[j].volume) left = middle; else right = middle; } queries[j].answer = stream[left]; j = previous_request[j]; } } for (i = 1; i <= queries_number; ++i){ printf("%d\n", queries[i].answer); } }

Compilation message (stderr)

fountain.cpp: In function 'int main()':
fountain.cpp:13:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   13 |     scanf( "%d%d", &height, &queries_number);
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fountain.cpp:23:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   23 |         scanf( "%d%hd", &reservoirs[i].diameter, &reservoirs[i].capacity);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fountain.cpp:25:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   25 |         scanf( "%d%d", &queries[i].level, &queries[i].volume);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...