# |
Submission time |
Handle |
Problem |
Language |
Result |
Execution time |
Memory |
763827 |
2023-06-22T23:19:01 Z |
matheuziz |
Fish (IOI08_fish) |
C++17 |
|
459 ms |
43372 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 rangeProd(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);
uint32_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 &[fLen, 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
// "steal" from the current fish
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);
uint32_t combinationsForKind;
auto cnt = (count[kind] % modulo);
auto c1 = tree.rangeProd(0, left - 1);
if (cnt) {
uint32_t c2 = kindIndex[kind] == left - 1 ? c1 : tree.rangeProd(0, kindIndex[kind]);
combinationsForKind = c1 + cnt * c2;
} else {
combinationsForKind = c1;
}
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 |
1 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 |
# |
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 |
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 |
130 ms |
6636 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 |
2 ms |
340 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
63 ms |
3144 KB |
Output is correct |
2 |
Correct |
69 ms |
3616 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
468 KB |
Output is correct |
2 |
Correct |
3 ms |
340 KB |
Output is correct |
3 |
Correct |
2 ms |
340 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
92 ms |
4620 KB |
Output is correct |
2 |
Correct |
168 ms |
6700 KB |
Output is correct |
3 |
Correct |
161 ms |
6972 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
146 ms |
6972 KB |
Output is correct |
2 |
Correct |
156 ms |
7384 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
88 ms |
4712 KB |
Output is correct |
2 |
Correct |
161 ms |
7288 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
146 ms |
7224 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
168 ms |
8376 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
150 ms |
8200 KB |
Output is correct |
2 |
Correct |
190 ms |
13756 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
283 ms |
16084 KB |
Output is correct |
2 |
Correct |
199 ms |
14528 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
259 ms |
16976 KB |
Output is correct |
2 |
Correct |
253 ms |
13780 KB |
Output is correct |
3 |
Correct |
272 ms |
20984 KB |
Output is correct |
4 |
Correct |
249 ms |
13788 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
364 ms |
20072 KB |
Output is correct |
2 |
Correct |
389 ms |
43372 KB |
Output is correct |
3 |
Correct |
413 ms |
43236 KB |
Output is correct |
4 |
Correct |
459 ms |
35480 KB |
Output is correct |