zoukankan      html  css  js  c++  java
  • 【cf1285E】E. Delete a Segment(vector+二分)

    传送门

    题意:
    给出(n)个区间,最终区间会合并为多个块。
    现在要删除一个区间,问最终剩下的块最多是多少个。

    思路:

    • 将区间按左端点排序后,考虑维护区间的前后缀,然后枚举要删除的区间;
    • 处理起来较麻烦,且维护的信息很多;
    • 所以直接维护前缀信息,然后倒着来枚举删除区间,同时动态维护后缀;
    • 统计答案时需要在后缀区间中二分,时间复杂度为(O(nlogn))

    细节见代码:

    /*
     * Author:  heyuhhh
     * Created Time:  2020/1/27 10:21:46
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #define MP make_pair
    #define fi first
    #define se second
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 2e5 + 5;
     
    int n;
    pii p[N];
    int pref[N], lst[N];
     
    void run(){
        cin >> n;
        for(int i = 1; i <= n; i++) {
            cin >> p[i].fi >> p[i].se;   
        }
        sort(p + 1, p + n + 1);
        pref[1] = 1, lst[1] = p[1].se;
        for(int i = 2; i <= n; i++) {
            if(p[i].fi <= lst[i - 1]) {
                pref[i] = pref[i - 1];
                lst[i] = max(lst[i - 1], p[i].se);
            } else {
                pref[i] = pref[i - 1] + 1;
                lst[i] = p[i].se;
            }   
        }
        vector <pii> v;
        int ans = 0;
        for(int i = n; i >= 1; i--) {
            int l = 0, r = sz(v), mid;
            while(l < r) {
                mid = (l + r) >> 1;
                if(v[mid].fi <= lst[i - 1]) r = mid;
                else l = mid + 1;
            }
            ans = max(ans, pref[i - 1] + l);
            while(!v.empty() && v.back().fi <= p[i].se) {
                p[i].se = max(p[i].se, v.back().se);   
                v.pop_back();
            }
            v.push_back(p[i]);
        }
        cout << ans << '
    ';
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        lst[0] = -INF;
        int T; cin >> T;
        while(T--) run();
        return 0;
    }
    
  • 相关阅读:
    Myeclipse新建 配置Hibernate
    MyEclipse从数据库表反向生成实体类之Hibernate方式(反向工程)
    简单使用JSON,JavaScript读取JSON文本(三)
    简单使用JSON,通过JSON 字符串来创建对象(二)
    简单使用JSON,JavaScript中创建 JSON 对象(一)
    【某deed网测题】D
    【题解】ACMICPC 2015 final L 哈弗曼树
    TC SRM 659 DIV1 500pt 插头DP
    BC#40D GCD值统计
    MS电面3轮
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/12241552.html
Copyright © 2011-2022 走看看