Submission #1346894

#TimeUsernameProblemLanguageResultExecution timeMemory
1346894kaze666Fish (IOI08_fish)C++20
95 / 100
463 ms78732 KiB
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define all(x) x.begin(), x.end()

int n, k, m, N;
vector<int> t, cnt, longest;
vector<vector<int>> v;

void build() {
    for (int i = 0; i < N; i++) t[i + N] = cnt[i] + 1;
    for (int i = N - 1; i > 0; i--) {
        t[i] = (t[i << 1] % m) * (t[i << 1 | 1] % m) % m;
    }
}
void update(int p, int val) {
    p += N;
    t[p] += val;
    for (p >>= 1; p > 0; p >>= 1) {
        t[p] = (t[p << 1] % m) * (t[p << 1 | 1] % m) % m;
    }
}
int query(int l, int r) {
    int res = 1;
    for (l += N, r += N; l < r; l >>= 1, r >>= 1) {
        if (l & 1) res = res * t[l++] % m;
        if (r & 1) res = res * t[--r] % m;
    }
    return res;
}
int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> k >> m;
    v.assign(k, vector<int>());
    for (int i = 0; i < n; i++) {
        int x, y; cin >> x >> y;
        v[--y].push_back(x);
    }
    for (int i = 0; i < k; i++) sort(all(v[i]));
    sort(v.begin(), v.end(), [](vector<int>& a, vector<int>& b) {
        return a.back() > b.back();
    });
    for (int i = k - 1; i >= 0; i--) {
        longest.push_back(v[i].back());
    }
    cnt.assign(k, 0);
    for (int i = 0; i < k; i++) cnt[i] = v[i].size();
    N = k;
    t.assign(2 * N, 1);
    build();
    priority_queue<pair<int,int>> pq;
    for (int i = 0; i < k; i++) {
        for (int x : v[i]) {
            pq.emplace(x, i);
        }
    }
    vector<vector<int>> dp(k, vector<int>(2, 0));
    for (int i = 0; i < k; i++) {
        int mx = v[i].back();
        while (!pq.empty() && pq.top().first > mx / 2) {
            auto top = pq.top(); pq.pop();
            int ttype = top.second;
            cnt[ttype]--;
            update(ttype, -1);
        }
        int c = upper_bound(all(v[i]), mx / 2) - v[i].begin();
        dp[i][0] = 1;
        dp[i][1] = c;
        dp[i][0] = dp[i][0] * query(i + 1, k) % m;
        dp[i][1] = dp[i][1] * query(i + 1, k) % m;
        if (c < (int)v[i].size()) {
            int idx = lower_bound(all(longest), 2 * v[i][c]) - longest.begin();
            int L = k - idx, R = i - 1;
            if (L <= R) {
                dp[i][0] = dp[i][0] * query(L, R + 1) % m;
            }
        }
    }
    int ans = 0;
    for (int i = 0; i < k; i++) {
        ans = (ans + dp[i][0] + dp[i][1]) % m;
    }
    cout << ans << '\n';
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...