首页 > 技术文章 > CSUST 玩游戏 题解(思维+优先队列维护第k大)

hunxuewangzi 2021-07-30 20:12 原文

题目链接

题目大意

注意是完全翻盖

思路

显然答案的左端点必定是某个区间的左端点,右端点必定是某个区间的右端点

枚举每个区间的做左端点,那么右端点必定是 左端点小于等于他的所有区间的右端点的第k大值

本来想用线段树维护第k大,但是郑教说可以直接优先队列维护,确实是这样,代码量--

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define fi first
#define se second
#define debug printf("aaaaaaaaaaa\n");
const int maxn=1e6+5,inf=0x3f3f3f3f,mod=998244353;
const ll INF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-7;
int n,k;
pair<int,int> pa[maxn];
int l[maxn],r[maxn];
int main(){
    while(scanf("%d%d",&n,&k)!=-1){
        priority_queue<int ,vector<int >,greater<int > >pq;
        for(int i=1;i<=n;i++){
            scanf("%d%d",&l[i],&r[i]);
            pa[i]={l[i],r[i]};
        }
        sort(pa+1,pa+1+n);
        int ans=0;
        for(int i=1;i<=n;i++){
            pq.push(pa[i].se);
            if(pq.size()>k) pq.pop();
            if(pq.size()==k){
                ans=max(ans,pq.top()-pa[i].fi);
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}


推荐阅读