1 solutions
-
0
Guest MOD
-
0
同一种颜色的线段必须互不相交。因此,对于按左端点排序后的线段,若选择某颜色,该颜色的最后一条线段的右端点必须小于当前线段的左端点。
算法思路排序:将线段按左端点升序排序,确保处理顺序为从左到右。
小根堆维护右端点:使用小根堆维护当前各颜色最后一条线段的右端点。堆顶为最小右端点,便于快速判断是否可重复使用颜色。可用资源槽计数:维护变量 表示当前可用的颜色槽数(包括可重复使用的旧颜色和未使用的新颜色)。初始时 ,每次使用一个槽后 减 ,释放旧槽时 增加。具体步骤排序线段:按左端点排序,确保处理顺序正确。初始化堆和变量:使用小根堆存储各颜色的最后右端点, 初始为 ,方案数 初始为 。遍历线段:弹出堆中所有右端点小于当前线段左端点的元素,释放对应颜色槽, 增加释放的槽数。方案数乘以当前可用槽数 ,取模。占用一个槽( 减 ),将当前线段的右端点加入堆中。
#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