# |
Submission time |
Handle |
Problem |
Language |
Result |
Execution time |
Memory |
761335 |
2023-06-19T13:54:30 Z |
matheuziz |
Fish (IOI08_fish) |
C++17 |
|
508 ms |
43368 KB |
#include <bits/stdc++.h>
#include <cstdint>
#include <cstdlib>
#include <stdint.h>
struct SegmentTree {
std::vector<uint32_t> tree;
uint32_t size, modulo;
SegmentTree(uint32_t numElements, uint32_t mod) {
size = numElements;
modulo = mod;
tree = std::vector<uint32_t>(2 * numElements, 1);
}
void update(uint32_t index, uint32_t value) {
index += size;
tree[index] = value % modulo;
auto parentIndex = index;
while (parentIndex /= 2) {
auto sonLeftIndex = parentIndex * 2;
auto sonRightIndex = sonLeftIndex + 1;
tree[parentIndex] = (tree[sonLeftIndex] * tree[sonRightIndex]) % modulo;
}
}
uint32_t range_prod(uint32_t start, uint32_t end) {
uint32_t product = 1;
if (end > size) return product;
start += size;
end += size;
// Traverse the range and accumulate the product
while (start <= end) {
if (start & 1) {
product = (product * tree[start]) % modulo;
start++;
}
if (!(end & 1)) {
product = (product * tree[end]) % modulo;
end--;
}
start /= 2;
end /= 2;
}
return product;
}
};
uint32_t calc_combinations(
const std::vector<std::pair<uint32_t, uint32_t>>& largest,
const std::vector<std::pair<uint32_t, uint32_t>>& fishes,
const std::vector<std::vector<uint32_t>>& lengthsByKind,
const std::vector<uint32_t>& kindIndex,
std::vector<uint32_t>& count,
const uint32_t& modulo
) {
SegmentTree tree(largest.size(), modulo);
size_t fishIndex = 0;
uint32_t answer = 0;
for (const auto &[length, kind] : largest) {
// Go through all fish that current can eat
// But start from previous big fish's index
while (fishIndex < fishes.size() && 2 * fishes[fishIndex].first <= length) {
auto &[_, fKind] = fishes[fishIndex];
count[fKind]++; // How many fishes have been eaten by kind
tree.update(kindIndex[fKind], count[fKind] + 1);
fishIndex++;
}
// Search over larger fishes of other kinds for the greatest fish that cannot
// catch more fish of the current kind.
uint32_t left = kindIndex[kind] + 1, right = largest.size() - 1;
while (left <= right) {
uint32_t mid = (left + right) / 2, eatableCount = 0;
for (auto small : lengthsByKind[kind]) {
if (small > largest[mid].first / 2) break;
eatableCount++;
}
if (eatableCount <= count[kind]) {
left = mid + 1;
} else {
right = mid - 1;
}
}
tree.update(kindIndex[kind], 1);
auto combinationsForKind = tree.range_prod(0, left - 1) +
(count[kind] % modulo) * tree.range_prod(0, kindIndex[kind]);
answer = (answer + combinationsForKind) % modulo;
tree.update(kindIndex[kind], count[kind] + 1);
}
return answer;
}
int main() {
uint32_t fishCount, gemCount, modulo;
if (scanf("%u\n%u\n%u", &fishCount, &gemCount, &modulo) != 3) {
exit(EXIT_FAILURE);
}
std::vector<std::pair<uint32_t, uint32_t>> fishes(fishCount), largest(gemCount, {0, 0});
std::vector<std::vector<uint32_t>> lengthsByKind(gemCount);
std::vector<uint32_t> kindIndex(gemCount), count(gemCount, 0);
for (auto &[length, kind] : fishes) {
if (scanf("%u %u", &length, &kind) != 2) {
exit(EXIT_FAILURE);
}
kind--;
largest[kind] = std::max(largest[kind], {length, kind});
}
std::sort(fishes.begin(), fishes.end());
std::sort(largest.begin(), largest.end());
for (size_t i = 0; i < largest.size(); i++) { kindIndex[largest[i].second] = i; }
for (const auto &[length, kind] : fishes) { lengthsByKind[kind].push_back(length); }
uint32_t answer = calc_combinations(
largest, fishes, lengthsByKind, kindIndex, count, modulo
);
printf("%d\n", answer);
}
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
0 ms |
212 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
0 ms |
212 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
0 ms |
212 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
0 ms |
212 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1 ms |
212 KB |
Output is correct |
2 |
Correct |
1 ms |
212 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1 ms |
212 KB |
Output is correct |
2 |
Correct |
132 ms |
6644 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1 ms |
212 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1 ms |
340 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
50 ms |
3144 KB |
Output is correct |
2 |
Correct |
65 ms |
3640 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1 ms |
468 KB |
Output is correct |
2 |
Correct |
3 ms |
380 KB |
Output is correct |
3 |
Correct |
2 ms |
396 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
97 ms |
4632 KB |
Output is correct |
2 |
Correct |
152 ms |
6720 KB |
Output is correct |
3 |
Correct |
173 ms |
13760 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
151 ms |
6972 KB |
Output is correct |
2 |
Correct |
167 ms |
7396 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
80 ms |
4724 KB |
Output is correct |
2 |
Correct |
155 ms |
7284 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
140 ms |
7228 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
165 ms |
8372 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
147 ms |
8200 KB |
Output is correct |
2 |
Correct |
188 ms |
13628 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
277 ms |
16076 KB |
Output is correct |
2 |
Correct |
216 ms |
14656 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
252 ms |
16852 KB |
Output is correct |
2 |
Correct |
236 ms |
13756 KB |
Output is correct |
3 |
Correct |
291 ms |
20984 KB |
Output is correct |
4 |
Correct |
245 ms |
13808 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
359 ms |
20072 KB |
Output is correct |
2 |
Correct |
445 ms |
43356 KB |
Output is correct |
3 |
Correct |
470 ms |
43368 KB |
Output is correct |
4 |
Correct |
508 ms |
35544 KB |
Output is correct |