51 node 区间交 优先队列(min(r),max(l))

本文介绍了一种解决特定区间交集问题的算法实现。针对给定的k个递增区间,通过使用优先队列来寻找这些区间共同交集内的最大数对应的和。通过排序和维护一个优先队列,确保每次迭代都能找到符合条件的区间组合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
链接:http://www.51nod.com/contest/Problem.html#!problemId=1672&contestId=58
题意 : k个区间共同交的最大数对应的和;
分析:窝们需要找到最满足条件的k个区间 进行不断更新取最大值;
首先由于原序列是递增的,因此维护一个优先队列,只需要将r小的放在前面即可;
由于优先队列已经存在了k个 因此窝们每次放进的当前node.l 都是最大的  但是优先队列维护的是最小的右端点;
因此对于这K个区间来说 node.r和a[i].l 就是需要找的最小的右端点和最大的左端点
************************tricsk******************
ll ans = 1e-18 WA    ...... hehe 
*/

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int maxn=4e5+7;
struct node{
    int l,r;
    friend operator <(node a,node b){
        return a.r>b.r;
    }
}a[maxn];

bool cmp(node a,node b){ return a.l<b.l||(a.l==b.l&&a.r<b.r);}

ll sum[maxn];

priority_queue<node>Q;

int main(){
    int n,k,m,x;scanf("%d %d %d",&n,&k,&m);
    sum[0]=0;
    for(int i=1;i<=n;i++) scanf("%d",&x),sum[i]=sum[i-1]+x;
    for(int i=1;i<=m;i++) scanf("%d %d",&a[i].l,&a[i].r);
    sort(a+1,a+m+1,cmp);
    ll ans=0;
    for(int i=1;i<=m;i++){
        Q.push(a[i]);
        int SZ=Q.size();
        if(Q.size()>k) Q.pop(),SZ--;
        if(Q.size()==k) ans=max(sum[Q.top().r]-sum[a[i].l-1],ans);
    }
    printf("%lld\n",ans);
    return 0;
}

 

### C++ STL 中 `priority_queue` 的使用与实现 #### 头文件引入 为了在程序中使用 `priority_queue`,需要包含 `<queue>` 头文件并声明标准命名空间 `std`[^2]。 ```cpp #include <queue> using namespace std; ``` #### 基本定义 `priority_queue` 是一种容器适配器,默认情况下它是一个最大堆(即顶部元素始终是最大的)。可以通过自定义比较函数来改变其行为。以下是常见的定义方式: 1. **默认优先级队列 (最大堆)** 定义一个存储整数的最大堆: ```cpp priority_queue<int> pq_max; ``` 2. **最小堆** 若要创建一个最小堆,则需提供自定义的比较函数。可以使用 `std::greater<T>` 来实现: ```cpp priority_queue<int, vector<int>, greater<int>> pq_min; ``` 3. **带自定义类型的优先队列** 如果希望处理更复杂的数据结构(如结构体),则需要定义相应的比较逻辑。例如,对于一个按某个字段排序的结构体: ```cpp struct Node { int value; string name; }; // 自定义比较函数:按照 value 字段升序排列 struct CompareNode { bool operator()(const Node& a, const Node& b) { return a.value > b.value; // 小顶堆 } }; priority_queue<Node, vector<Node>, CompareNode> pq_custom; ``` #### 常见操作 以下是一些常用的 `priority_queue` 操作及其说明: 1. **插入元素** 使用 `push()` 方法向队列中添加新元素。 ```cpp pq_max.push(10); pq_min.push(5); ``` 2. **访问顶部元素** 使用 `top()` 方法获取当前队列中的最高优先级元素(注意:此方法不会移除该元素)。 ```cpp cout << "Max element: " << pq_max.top() << endl; cout << "Min element: " << pq_min.top() << endl; ``` 3. **删除顶部元素** 调用 `pop()` 方法移除当前队列中的最高优先级元素。 ```cpp pq_max.pop(); pq_min.pop(); ``` 4. **判断是否为空** 可通过 `empty()` 方法检查队列是否为空。 ```cpp if (pq_max.empty()) { cout << "Priority queue is empty." << endl; } ``` 5. **获取大小** 使用 `size()` 方法返回队列中元素的数量。 ```cpp cout << "Size of max heap: " << pq_max.size() << endl; ``` #### 示例代码 下面展示了一个完整的例子,演示如何使用 `priority_queue` 创建最大堆和最小堆,并执行基本的操作。 ```cpp #include <iostream> #include <queue> #include <vector> #include <functional> using namespace std; int main() { // 默认最大堆 priority_queue<int> pq_max; pq_max.push(10); pq_max.push(30); pq_max.push(20); while (!pq_max.empty()) { cout << pq_max.top() << " "; // 输出顺序应为 30 20 10 pq_max.pop(); } cout << endl; // 最小堆 priority_queue<int, vector<int>, greater<int>> pq_min; pq_min.push(10); pq_min.push(30); pq_min.push(20); while (!pq_min.empty()) { cout << pq_min.top() << " "; // 输出顺序应为 10 20 30 pq_min.pop(); } return 0; } ``` 上述代码展示了如何分别构建最大堆和最小堆,并打印它们的内容[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值