HDU 5700 优先队列(或者multiset) 或 线段树

Posted 不知姓名的黑猫君

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 5700 优先队列(或者multiset) 或 线段树相关的知识,希望对你有一定的参考价值。

题目大意:有n个区间,求k个区间,使得这k个区间相交的区间内数字之和最大。数列的数字均>=0

优先队列思路:

按照左端点sort,然后枚举左端点,假设他被覆盖过k次,然后用优先队列来维护最右端即可。

//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\\n")
const int maxn = 100000 + 5;
int n, k, m;
LL a[maxn], sum[maxn];
vector<int> ve[maxn];
struct Point{
    int rb;
    bool operator < (const Point& a) const{
        return a.rb < rb;
    }
    Point(int x = 0): rb(x){};
};

int main(){
    while (scanf("%d%d%d", &n, &k, &m) == 3){
        memset(sum, 0, sizeof(sum));
        for (int i = 1; i <= n; i++){
            scanf("%lld", a + i);
            sum[i] = sum[i - 1] + a[i];
            ve[i].clear();
        }
        for (int i = 1; i <= m; i++){
            int u, v; scanf("%d%d", &u, &v);
            ve[u].push_back(v);
        }
        LL ans = 0;
        priority_queue<Point> que;
        for (int i = 1; i <= n; i++){
            for (int j = 0; j < ve[i].size(); j++){
                que.push(Point(ve[i][j]));
            }
            while (que.size() > k) que.pop();
            if (que.size() == k) ans = max(ans, sum[que.top().rb] - sum[i - 1]);
        }
        printf("%lld\\n", ans);
    }
    return 0;
}
View Code

 

线段树思路:

仔细一想,发现线段树思路其实也大致相同,最后只需要找线段树中cnt=k的就可以了

 

以上是关于HDU 5700 优先队列(或者multiset) 或 线段树的主要内容,如果未能解决你的问题,请参考以下文章

为啥使用 std::multiset 作为优先级队列比使用 std::priority_queue 更快?

HDU 1058 优先队列or堆

hdu 4725 The Shortest Path in Nya Graph(建图+优先队列dijstra)

HDU 4857 逃生(反向拓扑排序+优先队列)

HDU 2112 - HDU Today (优先队列)

HDU 1242 (BFS+优先队列)