Tokens on the Segments 题解(nlogn题解+贪心+优先队列)

2021/12/1 6:06:56

本文主要是介绍Tokens on the Segments 题解(nlogn题解+贪心+优先队列),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

题目链接

题目思路

网上我还没看到正解,感觉大家好像都是\(n^2logn\)甚至是更加高的复杂度,所以我决定水一篇题解

题意就是给你\(n\)条线段,要从每条线段选一个点放入一个集合中,求集合的最大\(size\)

我们设选点是从左往右

假设我们现在选的点\(pos\)为\(now\),那么显然下次选的点就是所有没有被选过的线段中\(l\leq now+1\)中\(r\)最小的点

我们把\(r\)放在一个优先队列里面,每次选了\(now\),我们就删除那个\(r\)最小的,然后加入所有左端点为\(now+1\)的

所有右端点的值

代码

#include<bits/stdc++.h>
#define fi first
#define se second
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
const int maxn=2e5+5,inf=0x3f3f3f3f,mod=1e9+7;
const double eps=1e-6;
int n;
int lsh[maxn];
struct node{
    int l,r;
}e[maxn];
int a[maxn];
vector<int> vec[maxn];
signed main(){
    int _;scanf("%d",&_);
    while(_--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d%d",&e[i].l,&e[i].r);
            lsh[i] = e[i].l;
            a[i]=e[i].l;
            vec[i].clear();
        }
        sort(a+1,a+1+n);
        a[n+1]=inf;
        sort(lsh+1 , lsh+n+1);
        int cnt = unique(lsh+1 , lsh+n+1) - lsh - 1;
        for(int i=1; i<=n; i++)
            vec[lower_bound(lsh+1 , lsh+cnt+1 , e[i].l) - lsh].push_back(e[i].r);
        int now=-1;
        int ans=0;
        lsh[cnt+1]=0;
        while(1){
            now=*lower_bound(a+1,a+1+n+1,now);
            if(now==inf) break;
            priority_queue<int,vector<int>,greater<int> > pq;
            int id=lower_bound(lsh+1 , lsh+cnt+1 , now) - lsh;
            for(auto x:vec[id]){
                pq.push(x);
            }
            while(!pq.empty()){
                if(pq.top()>=now){
                    now++;
                    ans++;
                    pq.pop();
                }else{
                    pq.pop();
                    continue;
                }
                if(now==*lower_bound(lsh+1 , lsh+cnt+1 , now)){
                    int id=lower_bound(lsh+1 , lsh+cnt+1 , now) - lsh;
                    for(auto x:vec[id]){
                        pq.push(x);
                    }
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}



这篇关于Tokens on the Segments 题解(nlogn题解+贪心+优先队列)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程