1285E

扫描线

先跑一个扫描线 统计不删除的答案 然后考虑对于每个线段计算删除的答案

思考一下什么情况下删除线段答案增加

当扫描线扫到了一个右端点 并且set里只有一条线段

这时set里的线段贡献+1 这里比较好思考

还要注意如果当前线段只有一条 那么答案-1

一条线段右端点也可能造成贡献 但是不用特别计算 因为全局答案包括了 可以想象成本身属于原先左右相交的线段的一部分 这样删除后不会对答案造成贡献

感觉大力想一想问题不大

#include <bits/stdc++.h>
using namespace std;
const int maxn = 4e5 + 5;
int n;
int cnt[maxn];
int main() {
    int T; scanf("%d", &T);
    while(T--) {
        scanf("%d", &n);
        vector<pair<int, int> > v;
        for(int i = 1; i <= n; ++i) {
            int l, r; 
            scanf("%d%d", &l, &r);
            v.emplace_back(l, -i);
            v.emplace_back(r, i);
            cnt[i] = 0;
        }    
        sort(v.begin(), v.end());
        v.emplace_back(0, 0);
        set<int> s;
        int ans = 0;
        for(int i = 0; i < (int)v.size() - 1; ++i) {
            if(v[i].second < 0) {
                s.insert(-v[i].second);
            } else {
                s.erase(v[i].second);
            }
            if(s.empty()) {
                ++ans;
            }
            if(s.size() == 1) {
                if(v[i].second > 0 && v[i + 1].second < 0 && v[i + 1].first > v[i].first) {
                    ++cnt[*s.begin()];
                } 
                if(v[i].second < 0 && v[i + 1].second > 0) {
                    --cnt[*s.begin()];
                }    
            }
        }
        int t = -1;
        for(int i = 1; i <= n; ++i) {
            t = max(t, cnt[i]);
        }
        printf("%d\n", ans + t);
    }
    return 0;
}
View Code

 

posted @ 2020-01-27 23:45  19992147  阅读(122)  评论(0编辑  收藏  举报