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;
    }
    
  • 相关阅读:
    pat甲级 1155 Heap Paths (30 分)
    pat甲级 1152 Google Recruitment (20 分)
    蓝桥杯 基础练习 特殊回文数
    蓝桥杯 基础练习 十进制转十六进制
    蓝桥杯 基础练习 十六进制转十进制
    蓝桥杯 基础练习 十六进制转八进制
    51nod 1347 旋转字符串
    蓝桥杯 入门训练 圆的面积
    蓝桥杯 入门训练 Fibonacci数列
    链表相关
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/12241552.html
Copyright © 2011-2022 走看看