• CF 1285E Delete a Segment


    好题  看似线段树的nlogn 实则是multiset + pair

     1 #include<bits/stdc++.h>
     2 #define fi first
     3 #define se second
     4 #define ll long long
     5 using namespace std;
     6 const int N = 2e5 + 10;
     7 pair<int, int> a[N << 1];
     8 int del[N];//del[i]表示删除第i个区间新增的union数 
     9 int main(){
    10     ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    11     int T; cin >> T;
    12     while(T--)
    13     {
    14         int n; cin >> n;
    15         for(int i = 1 ; i <= n ; i++){
    16             int l, r; cin >> l >> r;    
    17             a[i * 2 - 1] = {l, -i};
    18             a[i * 2] = {r, i};
    19             //对于相同位置x的端点,经过排序后左端点将会先被枚举到 
    20             del[i] = 0;
    21         }
    22         sort(a + 1, a + n * 2 + 1);
    23         multiset<int> s;
    24         int ans1 = 0;//一个都不删对应的union数 
    25         for(int i = 1 ; i <= n * 2 ; i++){
    26             if(a[i].se < 0)    s.insert(-a[i].se);//左端点插入 
    27             else    s.erase(s.find(a[i].second));//如果当前i对应右端点,则删除对应的左端点 
    28             if(s.size() == 0)    ans1++;
    29             if(s.size() == 1 && a[i].se > 0 && a[i + 1].se < 0 && a[i + 1].fi > a[i].fi)
    30                 del[*s.begin()]++;//当前为右端点且可匹配且下一个为左端点且位于当前右侧 
    31                 //则删除s中剩余的左端点对应线段必定在*处产生新空隙
    32                 //(size为1必定只剩下左端点)        [ [ ]*[
    33             if(s.size() == 1 && a[i].se < 0 && a[i + 1].se > 0)
    34                 del[*s.begin()]--;//单一线段 
    35         }
    36         int ans2 = INT_MIN;
    37         for(int i = 1 ; i <= n ; i++){
    38             ans2 = max(ans2, del[i]);
    39         }
    40         cout << ans1 + ans2 << endl;
    41     }
    42     return 0;
    43 }
  • 相关阅读:
    2020-03-03
    2020-03-02
    2020-03-01
    2020-02-29
    简单自我介绍
    福大软工1816 · 第六次作业
    福大软工1816 · 第五次作业
    python爬虫解决编码问题
    第四次作业-团队介绍
    福大软工1816 · 第三次作业
  • 原文地址:https://www.cnblogs.com/ecustlegendn324/p/14277991.html
Copyright © 2020-2023  润新知