• 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;
    }
    
    
    不摆烂了,写题
  • 相关阅读:
    内存中字的存储
    代码段
    CPU运行的流程
    字的传送
    内存中字的存储
    c语言中求数组元素的最大值和最小值
    linux系统 centos8.3 中安装 Rsudio
    Error in .External2(C_X11, paste0("png::", filename), g$width, g$height, : 解决linux R绘图问题
    linux系统中使用R的Cairo绘制png格式图片
    c语言中利用二维数组统计考试成绩之和
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/15627164.html
Copyright © 2020-2023  润新知