Too Many Segments CF595D 贪心乱搞

传送门!

比赛的时候没有时间写了,看看了看大佬的代码,学习学习。

一开始实验室大佬说是用差分写的,但是看了代码发现打cf的人大家都是stl狂魔!

贪心思路:区间按照左端点排序,从1~2e5遍历每一个点,不是遍历区间

如果有以该点为起点的区间则加入set并用pair记录右端点以及区间下标(pair第一维为右端点,从小到大排序)

当遍历到某一点的时候如果set的第一个及右端点最小的小于i就弹出去set

其实就是我们以set来记录同时存在的区间数,然后如果s.size()大于k就证明包含该点的区间数肯定大于K,即覆盖大于k次

删除set中右端点最靠右的那个,就是set的最后一个元素,这里就是贪心的意义。

//#pragma comment (linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
#include<stdio.h>
#include<string.h>
#include<string>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<set>
#include<stack>
#include<vector>
#include<map>
#include<queue>
#include<list>
#include<time.h>
#define myself i,l,r
#define lson i<<1
#define rson i<<1|1
#define Lson i<<1,l,mid
#define Rson i<<1|1,mid+1,r
#define half (l+r)/2
#define lowbit(x) x&(-x)
#define min4(a, b, c, d) min(min(a,b),min(c,d))
#define min3(x, y, z) min(min(x,y),z)
#define max3(x, y, z) max(max(x,y),z)
#define max4(a, b, c, d) max(max(a,b),max(c,d))
//freopen("E://1.in","r",stdin);
//freopen("E://1.out","w",stdout);
typedef unsigned long long ull;
typedef long long ll;
#define pii make_pair
#define pr pair<int,int>
const int inff = 0x3f3f3f3f;
const int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
const int mdir[8][2] = {0, 1, 0, -1, 1, 0, -1, 0, 1, 1, -1, 1, 1, -1, -1, -1};
const double eps = 1e-10;
const double PI = acos(-1.0);
const double E = 2.718281828459;
using namespace std;
const long long inFF = 9223372036854775807;
const int mod=1e9+7;
const int maxn=2e5+5;
vector<pr> v[maxn];//记录该店为起点的区间的右端点及编号
set<pr> s;
vector<int> ans;
int main()
{
    int n,k;
    ios::sync_with_stdio(false);
    cin>>n>>k;
    int x,y;
    for(int i=1;i<=n;i++)
    {
        cin>>x>>y;
        v[x].push_back(pii(y,i));
    }
    for(int i=1;i<=2e5;i++)
    {
        while(s.size()&&s.begin()->first<i) //如果某个区间右端点小于i删除
            s.erase(s.begin());
        for(auto x:v[i]) s.insert(x);//s中加入以i点为区间左端点的区间
        while(s.size()>k)
        {
            ans.push_back((--s.end())->second);//如果大于k则证明i点覆盖大于k次
            s.erase(--s.end());//贪心删除右端点最右边的那个
        }
    }
    cout<<ans.size()<<endl;
    for(auto x:ans) cout<<x<<" ";//auto是真好用vector中
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章