This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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 | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |