1 条题解
-
0
自动搬运
来自洛谷,原作者为

IC0CI
Huh搬运于
2025-08-24 23:18:09,当前版本为作者最后更新于2025-07-02 10:10:35,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题面分析
题目其实就是:给出 段区间 每段区间都有一个权值 ,问在 中哪个点覆盖该点的所有区间中权值最大的三个区间权值和最大,输出这个最大权值和。
关于具体实现
可以想到用类似单调队列的逻辑,依次遍历 的每个点,由每段区间的 决定其入队和出队顺序,维护在队列里的区间的权值。
容易想到可以用
priority_queue和set分别维护该队列和队列里权值,在入队和出队的时候顺便在集合加入和删除元素。需要注意的是,
set不可重,可以用增加一个元素或者使用multiset解决。Code
#include<bits/stdc++.h> using namespace std; #define ll long long int rd() //快读 const int N = 2e5 + 5; struct frog { int l,r,s,id; bool operator < (const frog &x) const { return r > x.r; } }f[N]; struct frog2 { int l,r,s,id; bool operator < (const frog2 &x) const { return (s == x.s) ? id < x.id : (s > x.s); } }; int T,n; bool cmp(frog x,frog y){ return x.l < y.l; } signed main() { T = rd(); while(T--) { n = rd(); for(int i = 1;i <= n;i++) { int x = rd(),s = rd(); f[i] = {max(0,i - x),min(n,i + x),s,i}; } sort(f + 1,f + n + 1,cmp); priority_queue<frog> q; set<frog2> ans; int j = 1; int res = 0; for(int i = 1;i <= n;i++) { while(!q.empty() && q.top().r < i) { frog x = q.top(); ans.erase({x.l,x.r,x.s,x.id}); q.pop(); } while(j <= n && f[j].l <= i) { q.push(f[j]); ans.insert({f[j].l,f[j].r,f[j].s,f[j].id}); j++; } int k = 1; auto it = ans.begin(); int cur = 0; while(k <= 3) { if(ans.size() < 3) break; cur += (*it).s; it++; k++; } res = max(res,cur); } cout << res << '\n'; } return 0; }
- 1
信息
- ID
- 12532
- 时间
- 3000ms
- 内存
- 512MiB
- 难度
- (无)
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者