bzoj 2006 [NOI2010]超级钢琴——ST表+堆
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2006
每个右端点的左端点在一个区间内;用堆记录端点位置、可选区间,按价值排序;拿出一个后也许分裂成两个。
第一次写了ST表,写得巨复杂,记录向前/后的最小值和位置,还为了预处理,又记 2^j 走到哪;调了半天边界,最后发现是Lg写错了!至今仍不知那样写为什么会错……
看看别人的代码,原来不用记两个方向的,用的时候往前跳几步再用向后的就行!也不用记录最小值,只要记录位置就行了;也不用记录 to[ ][ ] ,只要从 i+2^j 有没有超过n就能判断边界。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define ll long long
using namespace std;
const int N=5e5+,Lm=;
int n,m,L,R,a[N],s[N],Lg[N],stp[N][Lm+],stn[N][Lm+],to[N][Lm+];
int idp[N][Lm+],idn[N][Lm+];
ll ans;
struct Node{
int ps,to,l,r,v;
Node(int p,int t,int l,int r,int v):ps(p),to(t),l(l),r(r),v(v) {}
bool operator< (const Node &b) const
{return v<b.v;}
};
priority_queue<Node> q;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='') ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
return fx?ret:-ret;
}
void init()
{
/*
int i=1,cd=0,nxt;
for(;i<=n;i=nxt,cd++)
{
nxt=i<<1;
for(int j=i;j<nxt&&j<=n;j++) Lg[j]=cd;
}
i>>=1;
for(;i<=n;i++) Lg[i]=cd;
*/
for(int i=;i<=n;i++) Lg[i]=Lg[i>>]+; memset(to,0x3f,sizeof to);//
for(int i=;i<n;i++)
{
stp[i][]=s[i]; idp[i][]=i;
to[i][]=i-;
for(int j=,d;j<=Lm;j++)
{
d=to[i][j-];
if(d<||to[d][j-]>n)break;// >n!!! //if d<0
to[i][j]=to[d][j-];
if(stp[d][j-]<stp[i][j-])
{
stp[i][j]=stp[d][j-]; idp[i][j]=idp[d][j-];
}
else
{
stp[i][j]=stp[i][j-]; idp[i][j]=idp[i][j-];
}
}
}
memset(to,0x3f,sizeof to);
for(int i=n-;i>=;i--)
{
stn[i][]=s[i]; idn[i][]=i;
to[i][]=i+;
for(int j=,d;j<=Lm;j++)
{
d=to[i][j-];
if(to[d][j-]>n)break;
to[i][j]=to[d][j-];
if(stn[d][j-]<stn[i][j-])
{
stn[i][j]=stn[d][j-]; idn[i][j]=idn[d][j-];
}
else
{
stn[i][j]=stn[i][j-]; idn[i][j]=idn[i][j-];
}
}
}
}
int main()
{
n=rdn(); m=rdn(); L=rdn(); R=rdn();
for(int i=;i<=n;i++) a[i]=rdn(),s[i]=s[i-]+a[i];
init();
for(int i=,d,t;i<=n;i++)
{
int l=i-R,r=i-L;//not +1
if(r<) continue; l=max(l,);
t=Lg[r-l+];//not +1
d=(stp[r][t]<stn[l][t]?idp[r][t]:idn[l][t]);
q.push(Node(i,d,l,r,s[i]-s[d]));
} while(m--)
{
Node k=q.top(); q.pop(); ans+=k.v;
int l1=k.l,r1=k.to-, l2=k.to+,r2=k.r;
int t,d;
if(l1<=r1)
{
t=Lg[r1-l1+];
d=(stp[r1][t]<stn[l1][t]?idp[r1][t]:idn[l1][t]);
q.push(Node(k.ps,d,l1,r1,s[k.ps]-s[d]));
} if(l2<=r2)
{
t=Lg[r2-l2+];
d=(stp[r2][t]<stn[l2][t]?idp[r2][t]:idn[l2][t]);
q.push(Node(k.ps,d,l2,r2,s[k.ps]-s[d]));
}
}
printf("%lld\n",ans);
return ;
}
bzoj 2006 [NOI2010]超级钢琴——ST表+堆的更多相关文章
- BZOJ 2006: [NOI2010]超级钢琴 ST表+堆
开始想到了一个二分+主席树的 $O(n\log^2 n)$ 的做法. 能过,但是太无脑了. 看了一下题解,有一个 ST 表+堆的优美解法. 你发现肯定是选取前 k 大最优. 然后第一次选的话直接选固定 ...
- BZOJ 2006: [NOI2010]超级钢琴 [ST表+堆 | 主席树]
题意: 一个序列,求k个不相同的长度属于\([L,R]\)的区间使得和最大 前缀和,对于每个r找最小的a[l] 然后我yy了一个可持久化线段树做法...也许会T 实际上主席树就可以了,区间k小值 然后 ...
- [BZOJ2006][NOI2010]超级钢琴(ST表+堆)
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 3679 Solved: 1828[Submit][Statu ...
- 【BZOJ2006】[NOI2010]超级钢琴 ST表+堆
[BZOJ2006][NOI2010]超级钢琴 Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以 ...
- BZOJ 2006 NOI2010 超级钢琴 划分树+堆
题目大意:给定一个序列.找到k个长度在[l,r]之间的序列.使得和最大 暴力O(n^2logn),肯定过不去 看到这题的第一眼我OTZ了一下午... 后来研究了非常久别人的题解才弄明确怎么回事...蒟 ...
- Bzoj 2006: [NOI2010]超级钢琴 堆,ST表
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2222 Solved: 1082[Submit][Statu ...
- BZOJ 2006: [NOI2010]超级钢琴( RMQ + 堆 )
取最大的K个, 用堆和RMQ来加速... ----------------------------------------------------------------- #include<c ...
- 【BZOJ-2006】超级钢琴 ST表 + 堆 (一类经典问题)
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2473 Solved: 1211[Submit][Statu ...
- BZOJ 2006: [NOI2010]超级钢琴
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2613 Solved: 1297[Submit][Statu ...
随机推荐
- 关于Adapter对数据库的查询、删除操作
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzIxMDYyMA==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...
- C#自定义类型数组排序
在数组或者集合中对自定义类型进行排序分为两种方法. 1.如果这个自定义类型是自己定义编写的,那么我可以使它继承ICompareable<T>接口,实现其中的CompareTo(Object ...
- EasyUI基础入门之Droppable(可投掷)
怎么说呢Droppable这个单词究竟是什么意思,准确来说easyui作者究竟要表达什么意思,还是不大好拿捏的.只是没关系,没有必要纠结与这些细枝末节的东西,依据官网的demo效果,就简单的将之定义为 ...
- MyEclipse的html/JSP编辑器添加代码自动提示
http://lusterfly.iteye.com/blog/1872627 在myeclipse 9以前的版本中,我们如果要为html编辑器添加自动的代码提示可以这样操作: windows--&g ...
- c和c++的输入输出
格式输出: printf(格式控制, 输出表列); %d 十进制数 %md m为指定的宽度 若数据位数小于m,则左端补以空格;若大于m,则按实际位数输出 %ld 长整型数据 %mld 指定字段宽 ...
- Android调用JNI本地方法跟踪目标代码
正如Android调用JNI本地方法经过有点改变章所说跟踪代码是可行的,但是跟踪某些代码会出现anr,点击取消,还是不好运,有提高办法吗?回答是有(gdb还没试过,本文只讨论ida). 下面是我使用 ...
- kubernetes集群管理之通过jq来截取属性
系列目录 首先要声明,这里的jq并不是批前端框架里的jquery,而是一个处理json的命令行工具. jq工具相比yq,它更加成熟,功能也更加强大,主要表现在以下几个方面 支持递归查找(我点对我们平时 ...
- fedora delete openJDK
博客分类: linux 由于Fedora系统安装的时候会自带OpenJDK,安装完系统后 java -version 会显示 [root@localhost bin]# java -versio ...
- ubuntu 安装后的配置
osx 下用 vmware 安装了一个 ubuntu 虚拟机,版本是 14.04 server.安装完之后要做一系列配置,记录如下. 配置 Android 编译环境 sudo apt-get inst ...
- (转)Java web 项目中文件路径
文件路径分为绝对路径和相对路径,在项目中页面跳转.配置文件读写.文件上传下载等等许多地方都涉及到文件路径问题. 一篇好文转载于此:http://blog.csdn.net/shendl/archive ...