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中
}

 

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