# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
504134 | 2022-01-09T22:12:18 Z | gavgav | Fountain (eJOI20_fountain) | C++17 | 105 ms | 10464 KB |
// 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
# | 결과 | 실행 시간 | 메모리 | Grader output |
---|---|---|---|---|
1 | Correct | 0 ms | 288 KB | Output is correct |
2 | Correct | 1 ms | 204 KB | Output is correct |
3 | Correct | 1 ms | 204 KB | Output is correct |
4 | Correct | 1 ms | 296 KB | Output is correct |
5 | Correct | 1 ms | 332 KB | Output is correct |
6 | Correct | 1 ms | 372 KB | Output is correct |
7 | Correct | 1 ms | 332 KB | Output is correct |
# | 결과 | 실행 시간 | 메모리 | Grader output |
---|---|---|---|---|
1 | Correct | 65 ms | 7632 KB | Output is correct |
2 | Correct | 70 ms | 8064 KB | Output is correct |
# | 결과 | 실행 시간 | 메모리 | Grader output |
---|---|---|---|---|
1 | Correct | 0 ms | 288 KB | Output is correct |
2 | Correct | 1 ms | 204 KB | Output is correct |
3 | Correct | 1 ms | 204 KB | Output is correct |
4 | Correct | 1 ms | 296 KB | Output is correct |
5 | Correct | 1 ms | 332 KB | Output is correct |
6 | Correct | 1 ms | 372 KB | Output is correct |
7 | Correct | 1 ms | 332 KB | Output is correct |
8 | Correct | 65 ms | 7632 KB | Output is correct |
9 | Correct | 70 ms | 8064 KB | Output is correct |
10 | Correct | 1 ms | 304 KB | Output is correct |
11 | Correct | 41 ms | 4948 KB | Output is correct |
12 | Correct | 105 ms | 10464 KB | Output is correct |
13 | Correct | 89 ms | 10052 KB | Output is correct |
14 | Correct | 73 ms | 9372 KB | Output is correct |
15 | Correct | 65 ms | 9796 KB | Output is correct |