zoukankan      html  css  js  c++  java
  • 扫描线(线段树)+贪心 ZOJ 3953

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5572

    Intervals

    Time Limit: 1 Second      Memory Limit: 65536 KB      Special Judge

    Chiaki has n intervals and the i-th of them is [liri]. She wants to delete some intervals so that there does not exist three intervals ab and c such that a intersects with bb 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 ≤ nli ≠ 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;
    }
    View Code
  • 相关阅读:
    关于UltraISO打开iso文件后只有部分文件问题
    CollectionViewController 集合视图
    SDWebImage, 关于第三方异步加载图片的一些方法
    NSFileManager(文件管理类)
    UIReview(UI总结)
    sqlite( 轻量级数据库)
    DataPersistence(数据持久化: 文件读写, NSUserDefault, 归档)
    第三方(SDWebImage, 网络类AFNetWorking)
    网络编程(GET, POST)
    数据解析(SAX, JSON)
  • 原文地址:https://www.cnblogs.com/heimao5027/p/6690459.html
Copyright © 2011-2022 走看看