Portal --> bzoj2006

Solution

  一开始看错题了。。没有看到编号连续然后愣了好久==

​  首先肯定是找最大的\(K\)个啦,然后具体怎么找的话。。没有什么特别好的办法那就暴力一点,每次取最大值然后把它删掉然后再取这样

​  现在的问题是怎么找最大值

​  注意到一个很重要的点,因为这题要求一个和弦的音符编号是连续的一段(一个区间),所以我们可以按照区间的左端点分类,每一类形如\((st,l,r)\),表示左端点为\(st\),右端点\(\in[l,r]\)的区间集合,显然,当前的最大值一定是每一类最大值的最大值,那么如果说我们知道了每一类的最大值之后,将所有的类全部丢进一个堆里面就好了,至于删除的话,如果说我们可以定位这个最大值具体是哪个区间(假设为\([lx,rx]\)),那么我们只要把这个区间所在的类\((st,l,r)\)先删掉,然后再把\((st,l,lx-1)\)和\((st,rx+1,r)\)加进去就好了

​  那么最后的问题就是我们要寻求一种快速的计算\((st,l,r)\)这类区间的最大值的办法

​  既然是区间求和。。那当然是用前缀和啊,然后发现因为对于一类区间来说,左端点是固定的,所以我们只要比较这类区间中右端点处的前缀和即可比较大小,所以我们直接ST表RMQ一下就好了,这样也能很方便地定位具体是哪个区间

​  具体实现的话,可以每个类多加一个参数\(mx\),表示这类区间中区间和最大的那个区间为\([st,mx]\),然后。。堆里面的话各类区间比较的时候根据\(sum[mx]-sum[st-1]\)的大小比较就好了

  

​  mark:看清楚题目(是求和还是求第\(K\)大,是连续还是不连续,是否需要用long long)

​  mark:区间的问题的话。。是不是固定其中一点是套路。。?

  

​  代码大概长这个样子

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#define ll long long
using namespace std;
const int N=500010,TOP=20;
ll sum[N],a[N],mx[N][TOP+1];
struct Data{
int st,l,r,mx;
Data(){}
Data(int st1,int l1,int r1,int mx1){st=st1; l=l1; r=r1; mx=mx1;}
friend bool operator < (Data x,Data y){return sum[x.mx]-sum[x.st-1]<sum[y.mx]-sum[y.st-1];}
};
priority_queue<Data> q;
int n,m,L,R,K;
ll ans;
void prework(){
for (int i=1;i<=n;++i) mx[i][0]=i;
for (int j=1;j<=TOP;++j)
for (int i=n-(1<<j)+1;i>=1;--i)
if (sum[mx[i][j-1]]>sum[mx[i+(1<<j-1)][j-1]])
mx[i][j]=mx[i][j-1];
else
mx[i][j]=mx[i+(1<<j-1)][j-1];
}
int get_mx(int l,int r){
int len=r-l+1,lg=(int)(log(1.0*len)/log(2.0));
if (sum[mx[l][lg]]>sum[mx[r-(1<<lg)+1][lg]]) return mx[l][lg];
return mx[r-(1<<lg)+1][lg];
}
void solve(){
Data tmp;
while (!q.empty()) q.pop();
for (int i=1;i+L-1<=n;++i)
q.push(Data(i,i+L-1,min(i+R-1,n),get_mx(i+L-1,min(i+R-1,n))));
ans=0;
for (int i=1;i<=K;++i){
if (q.empty()) break;
tmp=q.top(); q.pop();
ans+=sum[tmp.mx]-sum[tmp.st-1];
//printf("%d\n",ans);
if (tmp.l<=tmp.mx-1)
q.push(Data(tmp.st,tmp.l,tmp.mx-1,get_mx(tmp.l,tmp.mx-1)));
if (tmp.mx+1<=tmp.r)
q.push(Data(tmp.st,tmp.mx+1,tmp.r,get_mx(tmp.mx+1,tmp.r)));
}
} int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
scanf("%d%d%d%d",&n,&K,&L,&R);
sum[0]=0;
for (int i=1;i<=n;++i) scanf("%lld",a+i),sum[i]=sum[i-1]+a[i];
prework();
solve();
printf("%lld\n",ans);
}

【bzoj2006】超级钢琴的更多相关文章

  1. BZOJ2006 超级钢琴

    Description ​ 给定一个长度为n的区间,询问前k大的区间和,区间长度\(\in [L, R]\). $ n, k <= 500000$ Solution ​ 首先求前缀和.把一个区间 ...

  2. [NOI2010][bzoj2006] 超级钢琴 [主席树/ST表+堆]

    题面: 传送门 思路: 首先容易想到用堆维护的O(n2logn)暴力 那么肯定就是在这个基础上套数据结构了[愉快] 然而我因为过于蒟蒻......只想得到主席树暴力***过去的方法 大概就是把前缀和算 ...

  3. bzoj2006 noi2010 超级钢琴 主席树 + 优先队列

    Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2435  Solved: 1195 Description 小 Z是一个小有名气的钢琴家,最近C博士送 ...

  4. 【BZOJ2006】超级钢琴(主席树,优先队列)

    [BZOJ2006]超级钢琴(主席树,优先队列) 题面 BZOJ 题解 既然是一段区间 首先就要变成单点 所以求一个前缀和 这个时候贪心很明显了: 枚举每一个点和可以和它组成一段的可行的点 全部丢进一 ...

  5. bzoj2006 [NOI2010]超级钢琴 (及其拓展)

    bzoj2006 [NOI2010]超级钢琴 给定一个序列,求长度在 \([L,\ R]\) 之间的区间和的前 \(k\) 大之和 \(n\leq5\times10^5,\ k\leq2\times1 ...

  6. 【BZOJ2006】【NOI2010】超级钢琴(主席树,优先队列)

    [BZOJ2006]超级钢琴(主席树,优先队列) 题面 BZOJ 题解 既然是一段区间 首先就要变成单点 所以求一个前缀和 这个时候贪心很明显了: 枚举每一个点和可以和它组成一段的可行的点 全部丢进一 ...

  7. 【BZOJ2006】[NOI2010]超级钢琴 ST表+堆

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

  8. 【BZOJ-2006】超级钢琴 ST表 + 堆 (一类经典问题)

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2473  Solved: 1211[Submit][Statu ...

  9. BZOJ2006[NOI2010]超级钢琴——堆+主席树

    题目描述 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中 ...

  10. bzoj千题计划162:bzoj2006: [NOI2010]超级钢琴

    http://www.lydsy.com/JudgeOnline/problem.php?id=2006 输出最大的k个 sum[r]-sum[l-1] (L<=r-l+1<=R) 之和 ...

随机推荐

  1. 180719-Quick-Task 动态脚本支持框架之使用介绍篇

    文章链接:https://liuyueyi.github.io/hexblog/2018/07/19/180719-Quick-Task-动态脚本支持框架之使用介绍篇/ Quick-Task 动态脚本 ...

  2. 420. Count and Say【LintCode java】

    Description The count-and-say sequence is the sequence of integers beginning as follows: 1, 11, 21, ...

  3. [寒假学习笔记](二)Python初学

    Python 学习 python的自学从几个月前断断续续地进行,想好好利用这个寒假,好好地学一学. 回顾 已学习:基本操作.函数 已有C++的一定基础,只要注意python中比较特殊的部分就行 进入正 ...

  4. 电脑提示‘您需要来自Administration的权限才能对此文件夹进行更改’怎么删除文件

    电脑提示'您需要来自Administration的权限才能对此文件夹进行更改'怎么删除文件 应该怎么做 win7系统需要定期删除一些无用的文件,扩大内存空间,但是在删除文件的时候弹出提示"您 ...

  5. ES6的新特性(21)——Proxy

    Proxy 概述 Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程. Proxy 可以理解成,在目标对 ...

  6. javascript提高篇

    本章简介 本章内容比较少,有三个分享的知识.你可能都看过了,因为网上也有很多提问和解答,如果没看过或者没搞懂,你可以再看看这篇文章. 1. 数组去重方法的演变    --  走向代码缩短化 2. [] ...

  7. Java GUI 点击按钮退出

    import java.awt.*; import java.awt.event.*; public class TestFrameTwo implements ActionListener { Fr ...

  8. 定时器应用-点击按钮,div向右移动

    需求是点击button,div就一直往右移动,给个条件left=800px就停止移动,通过定时器来控制. 代码如下: <!DOCTYPE html> <html> <he ...

  9. 如何在windows下Apache环境开启htaccess伪静态功能

     以下文章来自于网络,只做学习用 很多国人习惯用windows服务器或者在windows系统下调试PHP程序,在调试货使用的时候就遇到开启伪静态的各种问题,今天在网络上搜集了一些开启伪静态需要注意 ...

  10. Mac 常用快捷键整理

    Mac下常用的快捷键: Command+W 将当前窗口关闭(可以关闭Safari标签栏,很实用) Command+Option+M 将所有窗口最小化 Command+Q 关闭当前应用程序(相当于Doc ...