D - Intersecting Intervals
思路
對於區間重合問題, 經典做法 對 left 進行排序, 然後進行統計計數。
寫了一版TLE,反思有冗餘計數問題。
計算每一個區間的覆蓋數目, 不需要TLE版本逐個往後數,
只需要使用lower_bound找出第一個大於等於 ri + 1 的位置, 即可得到 與i區間 重合區間的數目。
Code (TLE)
https://atcoder.jp/contests/abc355/submissions/53886635
struct NODE{ int l; int r; }; int n; vector<struct NODE> c; bool cmp(struct NODE& a, struct NODE& b){ if (a.l < b.l){ return true; } return false; } int main() { cin >> n; c.resize(n); for(int i=0; i<n; i++){ cin >> c[i].l >> c[i].r; } sort(c.begin(), c.end(), cmp); // for(auto one: c){ // cout << one.l <<endl; // } long long cnt = 0; for(int i=0; i<n; i++){ struct NODE& cur = c[i]; int curl = cur.l; int curr = cur.r; for(int j=i+1; j<n; j++){ struct NODE& re = c[j]; // right elments int rel = re.l; int rer = re.r; if (rel > curr){ break; } cnt++; } } cout << cnt << endl; return 0; }
Code (PASS)
https://atcoder.jp/contests/abc355/submissions/53899306
struct NODE{ int l; int r; }; int n; vector<struct NODE> c; bool cmp(struct NODE& a, struct NODE& b){ if (a.l < b.l){ return true; } return false; } int main() { cin >> n; c.resize(n); for(int i=0; i<n; i++){ cin >> c[i].l >> c[i].r; } sort(c.begin(), c.end(), cmp); // for(auto one: c){ // cout << one.l <<endl; // } long long cnt = 0; for(int i=0; i<n; i++){ vector<struct NODE>::iterator it; it = lower_bound(c.begin(), c.end(), c[i].r+1, [](const struct NODE &a, const int &val) { return a.l < val; }); if (it == c.end()){ // cout << "to end" << endl; cnt += n-1 - i; continue; } int greatpos = it - c.begin(); cnt += (greatpos - i - 1); } cout << cnt << endl; return 0; }