Submission #688460

# Submission time Handle Problem Language Result Execution time Memory
688460 2023-01-27T13:25:02 Z finn__ Fish (IOI08_fish) C++17
100 / 100
752 ms 51760 KB
#include <bits/stdc++.h>
using namespace std;

class SegmentTree
{
    vector<unsigned> t;
    size_t l, m;

public:
    SegmentTree(size_t _n, size_t _m)
    {
        l = 1 << (32 - __builtin_clz(_n));
        m = _m;
        t = vector<unsigned>(2 * l, 1);
    }

    void update(size_t i, unsigned x)
    {
        i += l;
        t[i] = x % m;

        while (i >>= 1)
            t[i] = (t[2 * i] * t[2 * i + 1]) % m;
    }

    unsigned range_prod(size_t i, size_t j)
    {
        if (j > l)
            return 1;
        unsigned x = 1;
        i += l, j += l;

        while (i <= j)
        {
            if (i & 1)
                x = (x * t[i++]) % m;
            if (!(j & 1))
                x = (x * t[j--]) % m;
            i >>= 1;
            j >>= 1;
        }

        return x;
    }
};

int main()
{
    size_t n, k, m;
    cin >> n >> k >> m;

    vector<pair<unsigned, unsigned>> fish(n), largest(k, {0, 0});
    for (auto &[l, g] : fish)
    {
        cin >> l >> g;
        g--;
        largest[g] = max(largest[g], {l, g});
    }

    sort(fish.begin(), fish.end());
    sort(largest.begin(), largest.end());

    vector<vector<unsigned>> v(k);
    for (auto const &[l, g] : fish)
    {
        v[g].push_back(l);
    }

    vector<unsigned> t(k), c(k, 0);
    for (size_t i = 0; i < k; i++)
    {
        t[largest[i].second] = i;
    }

    size_t j = 0;
    SegmentTree tree(k, m);
    unsigned ans = 0;

    for (auto const &[l, g] : largest)
    {
        while (j < n && 2 * fish[j].first <= l)
        {
            c[fish[j].second]++;
            tree.update(t[fish[j].second], c[fish[j].second] + 1);
            j++;
        }

        unsigned a = t[g] + 1, b = k - 1;

        // Binary search over larger fishes for the greatest fish that cannot
        // catch more fish of type g.
        while (a <= b)
        {
            unsigned mid = (a + b) / 2;
            if (upper_bound(v[g].begin(), v[g].end(), largest[mid].first / 2) - v[g].begin() <= c[g])
            {
                a = mid + 1;
            }
            else
            {
                b = mid - 1;
            }
        }

        tree.update(t[g], 1);
        ans = (ans + tree.range_prod(0, a - 1) +
               (c[g] % m) * tree.range_prod(0, t[g])) %
              m;
        tree.update(t[g], c[g] + 1);
    }

    cout << ans << '\n';
}
# 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 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 330 ms 6768 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 3 ms 324 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 126 ms 3136 KB Output is correct
2 Correct 162 ms 3740 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 3 ms 452 KB Output is correct
2 Correct 5 ms 340 KB Output is correct
3 Correct 4 ms 440 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 202 ms 4692 KB Output is correct
2 Correct 369 ms 6620 KB Output is correct
3 Correct 342 ms 13808 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 315 ms 7044 KB Output is correct
2 Correct 347 ms 14584 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 207 ms 4712 KB Output is correct
2 Correct 350 ms 14228 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 331 ms 7328 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 379 ms 8608 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 322 ms 8296 KB Output is correct
2 Correct 427 ms 21728 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 498 ms 16884 KB Output is correct
2 Correct 352 ms 20168 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 418 ms 17784 KB Output is correct
2 Correct 508 ms 21724 KB Output is correct
3 Correct 490 ms 28080 KB Output is correct
4 Correct 569 ms 21640 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 594 ms 20560 KB Output is correct
2 Correct 614 ms 50780 KB Output is correct
3 Correct 752 ms 51760 KB Output is correct
4 Correct 739 ms 44612 KB Output is correct