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题解+贪心+优先队列)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南