文章目录

  • 题目描述
  • 解析
  • 代码

传送门

题目描述

解析

首先,如果只有一个和弦,那么问题显然简单了
前缀和结合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 贪心)相关推荐

  1. P2048 [NOI2010] 超级钢琴(ST表 + 优先队列优化)

    P2048 [NOI2010] 超级钢琴 题目 小 Z 是一个小有名气的钢琴家,最近 C 博士送给了小 Z 一架超级钢琴,小 Z 希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出 ...

  2. bzoj 2006 [NOI2010]超级钢琴 rmq+堆

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 3708  Solved: 1846 [Submit][Sta ...

  3. 洛谷 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]$是一个定值,所以我们只要在 ...

  4. P2048 [NOI2010]超级钢琴

    传送门 考虑维护前缀和 $sum[i]$ 那么对于每一个位置 $i$ ,左端点为 $i$ 右端点在 $[i+L-1,i+R-1]$ 区间的区间最大值容易维护 维护三元组 $(o,l,r)$ ,表示左端 ...

  5. BZOJ2006 [NOI2010]超级钢琴 【堆 + RMQ】

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MB Submit: 3446  Solved: 1692 [Submit][Sta ...

  6. NOI2010超级钢琴

    **NOI2010 超级钢琴** **Description** 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出 ...

  7. [NOI2010]超级钢琴 主席树

    [NOI2010]超级钢琴 链接 luogu 思路 和12省联考的异或粽子一样. 堆维护n个左端点,每次取出来再放回去次 代码 #include <bits/stdc++.h> #defi ...

  8. 贪心(数据结构):COGS 468. [NOI2010]超级钢琴

    ★★★☆   输入文件:piano.in   输出文件:piano.out   简单对比 时间限制:2 s   内存限制:512 MB 超级钢琴 [问题描述] 小Z是一个小有名气的钢琴家,最近C博士送 ...

  9. [NOI2010] 超级钢琴

    题目类型:RMQ+堆 传送门:>Here< 题意:给出一个长度为\(N\)的序列\(a\),对于每一个\(i\)作为和弦的起点,长度可以是\(L \rightarrow R\).问所有和弦 ...

最新文章

  1. 博士后工作站来了!智源研究院获得正式授牌
  2. java读取dcm影像文件_使用dcmtk库读取.dcm文件并获取信息+使用OpenCV显示图像
  3. SAP Tax计算逻辑
  4. FIle类常用工具方法整理(持续更新)
  5. Quoit Design
  6. *SQL Server系统表的应用
  7. java安装没有jdk文件_java文件在没有安装jdk的windows下运行。
  8. 最浅显的IE反劫持攻略(转)
  9. mysql类目树关系的保存和全排列查询
  10. DS18B20 引脚 定义 单总线 多点温度检测 STM32 单片机
  11. 反转字符串中的元音字母Python解法
  12. 收官之战,年终的财务分析如何做?
  13. linux 显示器识别工具,Linux 显示器未正确识别 最佳分辨率 Ubuntu 10.10 X1
  14. 计算机控制 英文 论文,计算机论文英文翻译
  15. oracle ebs fsg报表,Oracle EBS FSG报表迁移
  16. 钒酸钠的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  17. 怎么生成永久二维码?怎么做出长期有效的图片二维码?
  18. 中国电子学会2022年12月份青少年软件编程Python等级考试试卷四级真题(含答案)
  19. CCS3.3相关驱动插件安装
  20. Rockchip Linux CMA开发文档

热门文章

  1. 2017年终奖发放,程序员人均11776元排名第一!
  2. 2018年,该转行AI工程师吗?
  3. php运算符优先级题目,详解php运算符优先级
  4. 摇滚java游戏_java 集合类
  5. php tp3 操作绑定到类,操作绑定到类 · ThinkPHP3.2.3完全开发手册 · 看云
  6. spyder pyecharts不显示_我的显示器需要定时校色吗?
  7. csdn上修改字体的颜色
  8. [JavaWeb-HTML]HTML标签_表单标签
  9. Prototype(原型)--对象创建模式
  10. number two