cf612 D. The Union of k-Segments(被至少K條線段覆蓋的所有區間)
阿新 • • 發佈:2022-04-22
題意:
給定n條線段,如果一個實數點被至少K條線段覆蓋,稱為好點。輸出一列總長度最小的、包含所有好點的閉區間
輸入均為整數
思路:
傳世經典題。
差分思想:想象一個實數軸,所有線段左端點座標處打上1標記,右端點打上-1。對所涉所有座標排序,計算字首和 k。根據當前的 k 可以判斷當前點被覆蓋的情況
int n, K; vector<PII> ve; //位置,型別 vector<PII> ans; //答案 signed main() { iofast; cin >> n >> K; for(int i = 1; i <= n; i++) { int l, r; cin >> l >> r; ve.pb({l, 1}), ve.pb({r, -1}); } sort(all(ve), [](PII &x, PII &y) { //保證先加再減 return x.fi != y.fi ? x.fi < y.fi : x.se > y.se; }); int k = 0; for(auto &[p,t] : ve) { if(k == K - 1 && t == 1) ans.pb({p,0}); if(k == K && t == -1) ans.back().se = p; k += t; } cout << ans.size() << endl; for(auto &[l,r] : ans) cout << l << ' ' << r << endl; }
細節可以稍有不同:
for(int i = 1; i <= n; i++) { int l, r; cin >> l >> r; ve.pb({l, 1}), ve.pb({r + 1, -1}); //這樣 } sort(all(ve)); //這樣 int k = 0; for(auto &[p,t] : ve) { if(k == K - 1 && t == 1) ans.pb({p,0}); if(k == K && t == -1) ans.back().se = p-1;//這樣 k += t; }