http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5572
Chiaki has n intervals and the i-th of them is [li, ri]. She wants to delete some intervals so that there does not exist three intervals a, b and c such that a intersects with b, b intersects with c and c intersects with a.
Chiaki is interested in the minimum number of intervals which need to be deleted.
Note that interval a intersects with interval b if there exists a real number x such that la ≤ x ≤ ra and lb ≤ x ≤ rb.
Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
The first line contains an integer n (1 ≤ n ≤ 50000) -- the number of intervals.
Each of the following n lines contains two integers li and ri (1 ≤ li < ri ≤ 109) denoting the i-th interval. Note that for every 1 ≤ i < j ≤ n, li ≠ lj or ri ≠ rj.
It is guaranteed that the sum of all n does not exceed 500000.
Output
For each test case, output an integer m denoting the minimum number of deletions. Then in the next line, output m integers in increasing order denoting the index of the intervals to be deleted. If m equals to 0, you should output an empty line in the second line.
Sample Input
1 11 2 5 4 7 3 9 6 11 1 12 10 15 8 17 13 18 16 20 14 21 19 22
Sample Output
4 3 5 7 10
Author: LIN, Xi
Source: The 17th Zhejiang University Programming Contest Sponsored by TuSimple
题目大意:给你n个区间,这n个区间里面可能存在这样的区间,即a交b,b交c,c交a。问最少删除多少个,才能使得不存在这样的区间,并输出删除的是什么区间。
思路:扫面线一遍,从左往右扫(就是单点查询,md我今天才知道原来这是一维扫描线,打比赛的时候完全不知道)。然后每次都往priority_queue里面放入目前询问到节点的右端点,当cnt>=3的时候贪心的删除最右边的端点即可。
//看看会不会爆int!数组会不会少了一维! //取物问题一定要小心先手胜利的条件 #include <bits/stdc++.h> using namespace std; #pragma comment(linker,"/STACK:102400000,102400000") #define LL long long #define ALL(a) a.begin(), a.end() #define pb push_back #define mk make_pair #define fi first #define se second #define haha printf("haha ") const int maxn = 100000 + 5; int n; vector<int> ve; int l[maxn], r[maxn]; vector<pair<int, int> > qujian[maxn]; struct Point{ int val, lazy; }tree[maxn << 2]; void buildtree(int l, int r, int o){ tree[o].val = tree[o].lazy = 0; if (l == r){ return ; } int mid = (l + r) / 2; if (l <= mid) buildtree(l, mid, o << 1); if (r > mid) buildtree(mid + 1, r, o << 1 | 1); } void push_down(int o){ int lb = o << 1, rb = o << 1 | 1; tree[lb].lazy += tree[o].lazy; tree[lb].val += tree[o].lazy; tree[rb].lazy += tree[o].lazy; tree[rb].val += tree[o].lazy; tree[o].lazy = 0; } void update(int ql, int qr, int l, int r, int o, int add){ //printf("ql = %d qr = %d l = %d r = %d ", ql, qr, l, r); if (ql <= l && qr >= r){ tree[o].lazy += add; tree[o].val += add; return ; } if (tree[o].lazy != 0) push_down(o); int mid = (l + r) / 2; if (ql <= mid) update(ql, qr, l, mid, o << 1, add); if (qr > mid) update(ql, qr, mid + 1, r, o << 1 | 1, add); tree[o].val = max(tree[o << 1].val, tree[o << 1 | 1].val); } int query(int ql, int qr, int l, int r, int o){ if (ql <= l && qr >= r){ return tree[o].val; } if (tree[o].lazy != 0) push_down(o); int mid = (l + r) / 2; int maxval = 0; if (ql <= mid) maxval = max(maxval, query(ql, qr, l, mid, o <<1)); if (qr > mid) maxval = max(maxval, query(ql, qr, mid + 1, r, o << 1| 1)); tree[o].val = max(tree[o << 1].val, tree[o << 1 | 1].val); return maxval; } void solve(){ int ans = 0; vector<int> tmp; buildtree(1, 2 * n, 1); for (int i = 1; i <= n; i++){ update(l[i], r[i], 1, 2 * n, 1, 1); } priority_queue<pair<int, int> > que; for (int i = 1; i <= 2 * n; i++){ if (qujian[i].size()){ for (int j = 0; j < qujian[i].size(); j++){ que.push(qujian[i][j]); } int cnt = query(i, i, 1, 2 * n, 1); while (cnt >= 3){ cnt--; pair<int, int> pa = que.top(); que.pop(); update(i, pa.fi, 1, 2*n, 1, -1); ans++; tmp.push_back(pa.se); } /*for (int j = qujian[i].size() - 1; j >= 0; j--){ int L = i, R = qujian[i][j].fi; int cnt = query(L, R, 1, 2 * n, 1); cout<<L << ' ' << R<< ' ' <<cnt<<endl; if (cnt >= 3){ ans++; update(L, R, 1, 2 * n, 1, -1); tmp.push_back(qujian[i][j].se); } else break; }*/ } } sort(ALL(tmp)); printf("%d ", ans); for (int i = 0; i < tmp.size(); i++){ printf("%d%c", tmp[i], i == tmp.size()-1 ? ' ' : ' '); } } int main(){ int t; cin >> t; while (t--){ ve.clear(); scanf("%d", &n); for (int i = 0; i <= 2 * n; i++) qujian[i].clear(); for (int i = 1; i <= n; i++){ scanf("%d%d", l + i, r + i); ve.push_back(l[i]); ve.push_back(r[i]); } sort(ALL(ve)); ve.erase(unique(ALL(ve)), ve.end()); for (int i = 1; i <= n; i++){ l[i] = lower_bound(ALL(ve), l[i]) - ve.begin() + 1; r[i] = lower_bound(ALL(ve), r[i]) - ve.begin() + 1; qujian[l[i]].push_back(mk(r[i], i)); } for (int i = 1; i <= 2 * n; i++){ if (qujian[i].size()){ sort(ALL(qujian[i])); } } solve(); } return 0; }