1 solutions

  • 0
    @ 2025-5-20 21:55:46

    同一种颜色的线段必须互不相交。因此,对于按左端点排序后的线段,若选择某颜色,该颜色的最后一条线段的右端点必须小于当前线段的左端点。

    算法思路排序:将线段按左端点升序排序,确保处理顺序为从左到右。

    小根堆维护右端点:使用小根堆维护当前各颜色最后一条线段的右端点。堆顶为最小右端点,便于快速判断是否可重复使用颜色。可用资源槽计数:维护变量 temtem 表示当前可用的颜色槽数(包括可重复使用的旧颜色和未使用的新颜色)。初始时 tem=ktem = k,每次使用一个槽后 temtem 减 11,释放旧槽时 temtem 增加。具体步骤排序线段:按左端点排序,确保处理顺序正确。初始化堆和变量:使用小根堆存储各颜色的最后右端点,temtem 初始为 kk ,方案数 ansans 初始为 11。遍历线段:弹出堆中所有右端点小于当前线段左端点的元素,释放对应颜色槽,temtem 增加释放的槽数。方案数乘以当前可用槽数 temtem,取模。占用一个槽(temtem 减 11),将当前线段的右端点加入堆中。

    #include <iostream>
    #include <queue>
    #include <vector>
    #include <algorithm>
    using namespace std;
    #define int long long
    typedef pair<int, int> PII;
    const int mod = 998244353;
    
    signed main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        
        int n, k;
        cin >> n >> k;
        
        vector<PII> A(n);
        for (int i = 0; i < n; ++i) {
            cin >> A[i].first >> A[i].second;
        }
        
        sort(A.begin(), A.end()); // 按左端点排序
        
        priority_queue<int, vector<int>, greater<int>> heap; // 小根堆,存储右端点
        int tem = k;
        int ans = 1;
        
        for (const auto& seg : A) {
            int a = seg.first, b = seg.second;
            // 弹出所有右端点 < a 的线段,释放颜色槽
            while (!heap.empty() && heap.top() < a) {
                heap.pop();
                tem++;
            }
            // 方案数乘以可用槽数
            ans = 1LL * ans * tem % mod;
            // 占用一个槽,更新右端点
            tem--;
            heap.push(b);
        }
        
        cout << ans << endl;
        return 0;
    }
    
    
    • 1

    Information

    ID
    1483
    Time
    2000ms
    Memory
    256MiB
    Difficulty
    7
    Tags
    (None)
    # Submissions
    36
    Accepted
    8
    Uploaded By