P2048 [NOI2010] 超级钢琴(RMQ 贪心)
文章目录
- 题目描述
- 解析
- 代码
传送门
题目描述
解析
首先,如果只有一个和弦,那么问题显然简单了
用前缀和结合ST表随便做做即可
然而
这次要求前k大的
怎么办呢?
参照之前有一道序列合并的做法
我们想到,可以先建一个优先队列,把以每个元素为开头的最大和弦求出来
然后每次弹出队首,再用队首的开头把加进来一些新的
问题是,我受那道题影响,觉得一定要加进来次大的
次大弹出就加第三大的,子子孙孙无穷匮也…
于是我就卡到这里了
----------我的思路和题解的分割线-------------
但是不必拘泥与原来的那个区间
可以把它拆开来
用三元组(st,l,r)表示st开头,终点在[l,r]的最大值和最大值位置
那么取出一个最大值位置在pl的三元组后,可以再弹进去两个:
(st,l,pl-1)(st,pl+1,r)
当然,要注意一些pl在边缘的特判
这样就迎刃而解啦
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=5e5+100;
int n,m,k;
int l,r;
int a[N],sum[N];
struct node{int st,l,r,pl,v;bool operator < (const node y)const{return v<y.v;}
};
struct node2{int v,pl;
};
node2 mx[N][25];
node2 merge(node2 x,node2 y){if(x.v>y.v) return x;else return y;
}
int mi[N],lg[N];
void solve(){mi[0]=1;for(int i=1;i<=20;i++) mi[i]=mi[i-1]<<1;int k=0;for(int i=1;i<=n;i++){if(i>=mi[k]) k++;lg[i]=k-1;}for(int i=1;i<=n;i++) mx[i][0]=(node2){sum[i],i};for(int k=1;k<=lg[n];k++){for(int i=1;i+mi[k]-1<=n;i++){mx[i][k]=merge(mx[i][k-1],mx[i+mi[k-1]][k-1]);}}return;
}
node2 ask(int x,int y){int k=lg[y-x+1];return merge(mx[x][k],mx[y-mi[k]+1][k]);
}
priority_queue<node>q;
int main(){scanf("%d%d%d%d",&n,&k,&l,&r);for(int i=1;i<=n;i++) scanf("%d",&a[i]),sum[i]=sum[i-1]+a[i];solve();for(int i=1;i<=n;i++){if(i+l-1>n) break;int L=i+l-1,R=min(n,i+r-1);node2 x=ask(L,R);q.push((node){i,L,R,x.pl,x.v-sum[i-1]});}ll tot=0;for(int i=1;i<=k;i++){node o=q.top();q.pop();tot+=o.v;int st=o.st;if(o.pl!=o.l){node2 x=ask(o.l,o.pl-1);q.push((node){st,o.l,o.pl-1,x.pl,x.v-sum[st-1]});}if(o.pl!=o.r){node2 x=ask(o.pl+1,o.r);q.push((node){st,o.pl+1,o.r,x.pl,x.v-sum[st-1]});}}printf("%lld",tot);return 0;
}
/*
6
2002 4920
2003 5901
2004 2832
2005 3890
2007 5609
2008 3024
5
2002 2005
2003 2005
2002 2007
2003 2007
2005 2008
*/
P2048 [NOI2010] 超级钢琴(RMQ 贪心)相关推荐
- P2048 [NOI2010] 超级钢琴(ST表 + 优先队列优化)
P2048 [NOI2010] 超级钢琴 题目 小 Z 是一个小有名气的钢琴家,最近 C 博士送给了小 Z 一架超级钢琴,小 Z 希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出 ...
- bzoj 2006 [NOI2010]超级钢琴 rmq+堆
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 3708 Solved: 1846 [Submit][Sta ...
- 洛谷 P2048 [NOI2010]超级钢琴(优先队列,RMQ)
传送门 我们定义$(p,l,r)=max\{sum[t]-sum[p-1],p+l-1\leq t\leq p+r-1 \}$ 那么因为对每一个$p$来说$sum[p-1]$是一个定值,所以我们只要在 ...
- P2048 [NOI2010]超级钢琴
传送门 考虑维护前缀和 $sum[i]$ 那么对于每一个位置 $i$ ,左端点为 $i$ 右端点在 $[i+L-1,i+R-1]$ 区间的区间最大值容易维护 维护三元组 $(o,l,r)$ ,表示左端 ...
- BZOJ2006 [NOI2010]超级钢琴 【堆 + RMQ】
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MB Submit: 3446 Solved: 1692 [Submit][Sta ...
- NOI2010超级钢琴
**NOI2010 超级钢琴** **Description** 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出 ...
- [NOI2010]超级钢琴 主席树
[NOI2010]超级钢琴 链接 luogu 思路 和12省联考的异或粽子一样. 堆维护n个左端点,每次取出来再放回去次 代码 #include <bits/stdc++.h> #defi ...
- 贪心(数据结构):COGS 468. [NOI2010]超级钢琴
★★★☆ 输入文件:piano.in 输出文件:piano.out 简单对比 时间限制:2 s 内存限制:512 MB 超级钢琴 [问题描述] 小Z是一个小有名气的钢琴家,最近C博士送 ...
- [NOI2010] 超级钢琴
题目类型:RMQ+堆 传送门:>Here< 题意:给出一个长度为\(N\)的序列\(a\),对于每一个\(i\)作为和弦的起点,长度可以是\(L \rightarrow R\).问所有和弦 ...
最新文章
- 博士后工作站来了!智源研究院获得正式授牌
- java读取dcm影像文件_使用dcmtk库读取.dcm文件并获取信息+使用OpenCV显示图像
- SAP Tax计算逻辑
- FIle类常用工具方法整理(持续更新)
- Quoit Design
- *SQL Server系统表的应用
- java安装没有jdk文件_java文件在没有安装jdk的windows下运行。
- 最浅显的IE反劫持攻略(转)
- mysql类目树关系的保存和全排列查询
- DS18B20 引脚 定义 单总线 多点温度检测 STM32 单片机
- 反转字符串中的元音字母Python解法
- 收官之战,年终的财务分析如何做?
- linux 显示器识别工具,Linux 显示器未正确识别 最佳分辨率 Ubuntu 10.10 X1
- 计算机控制 英文 论文,计算机论文英文翻译
- oracle ebs fsg报表,Oracle EBS FSG报表迁移
- 钒酸钠的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
- 怎么生成永久二维码?怎么做出长期有效的图片二维码?
- 中国电子学会2022年12月份青少年软件编程Python等级考试试卷四级真题(含答案)
- CCS3.3相关驱动插件安装
- Rockchip Linux CMA开发文档
热门文章
- 2017年终奖发放,程序员人均11776元排名第一!
- 2018年,该转行AI工程师吗?
- php运算符优先级题目,详解php运算符优先级
- 摇滚java游戏_java 集合类
- php tp3 操作绑定到类,操作绑定到类 · ThinkPHP3.2.3完全开发手册 · 看云
- spyder pyecharts不显示_我的显示器需要定时校色吗?
- csdn上修改字体的颜色
- [JavaWeb-HTML]HTML标签_表单标签
- Prototype(原型)--对象创建模式
- number two