洛谷$P$2048 超级钢琴 $[NOI2010]$ $rmq$/主席树
正解:$rmq$/主席树
解题报告:
好像看过这题挺多次辣,,,$QwQ$
之前$NOIp$的时候$cjk$学长讲课讲了这题(虽然那时候的$gql$太菜辣并麻油落实这道_(:з」∠)_,然后寒假考试考了这道,然后现在说搞下主席树又碰到这题辣_(:з」∠)_
昂然后先港下题意,,,大概就给定一个序列求前$k$大区间和$QwQ$
分别港下$rmq$和主席树趴$QwQ$
先港$rmq$趴$QwQ$
首先区间求和显然先搞下前缀和,这个显然是要有的$QwQ$
考虑设$f_{i,l,r}$表示左端点在$i$,右端点在$[l,r]$区间内的区间和$max$,区间求最值这个显然就考虑$rmq$就好昂$QwQ$
然后考虑在找到一个最大值之后怎么搞昂$QAQ$?假如当前求出的右端点在$k$,因为要求不能重复,也就相当于右端点不能取$k$了,那原右端点区间就能拆成$[l,k-1]$和$[k+1,r]$
欧克这时候思路就差不多已经清晰辣!就考虑先预处理一个$st$表,然后开一个$set$或者$priority\text{_}queue$之类的东西,然后把(i,l,r)作为状态存进去,每次弹出队首之后就把$(i,l,k-1)$和(i,k+1,r)继续弹进去,然后一直做下去知道有$k$个元素为止
然后就做完辣辣辣辣!
放下$rmq$的代码昂$QwQ$
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define ll long long
#define rg register
#define gc getchar()
#define lowbit(x) (x&(-x))
#define rp(i,x,y) for(rg int i=x;i<=y;++i)
#define my(i,x,y) for(rg ll i=x;i>=y;--i) const ll N=5e5+;
ll n,k,l,r,sum[N],st[N][],id[N][],to[N][],lg[N],poww[]={},as;
struct node{ll l,r,mxpos,id;bool operator <(node gdgs)const{return sum[mxpos]-sum[id-]<sum[gdgs.mxpos]-sum[gdgs.id-];}};
priority_queue<node>Q; il ll read()
{
rg char ch=gc;rg int x=;rg bool y=;
while(ch!='-' && (ch>'' || ch<''))ch=gc; if(ch=='-')ch=gc,y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
return y?x:-x;
}
il void prelg(){rp(i,,n)lg[i]=lg[i/]+;rp(i,,)poww[i]=poww[i-]<<;}
il void prest()
{
rp(i,,)
rp(j,,n)
{
to[j][i]=to[to[j][i-]+][i-];
if(st[j][i-]>st[to[j][i-]+][i-])st[j][i]=st[j][i-],id[j][i]=id[j][i-];
else st[j][i]=st[to[j][i-]+][i-],id[j][i]=id[to[j][i-]+][i-];
}
}
il ll rmq(ll l,ll r){if(l==r)return l;ll len=lg[r-l+];if(st[l][len]>st[r-poww[len]+][len])return id[l][len];return id[r-poww[len]+][len];} int main()
{
n=read();k=read();l=read();r=read();rp(i,,n)st[i][]=sum[i]=sum[i-]+read(),to[i][]=id[i][]=i;prelg();prest();
rp(i,,n-l+)Q.push((node){i+l-,min(i+r-,n),rmq(i+l-,min(i+r-,n)),i});
while(k--)
{
node gg=Q.top();Q.pop();as+=sum[gg.mxpos]-sum[gg.id-];
if(gg.mxpos->=gg.l)Q.push((node){gg.l,gg.mxpos-,rmq(gg.l,gg.mxpos-),gg.id});;
if(gg.mxpos+<=gg.r)Q.push((node){gg.mxpos+,gg.r,rmq(gg.mxpos+,gg.r),gg.id});
}
printf("%lld\n",as);
return ;
}
然后再港下,主席树的做法$QwQ$
其实依然是考虑用一个$priority\text{_}queue$维护,只是求最值的方法会改变.
考虑用主席树求区间最大值,板子,做完辣
$over$
代码是不可能有代码的,,,$QwQ$
随机推荐
- HZOJ big
考试的时候理解错题了(无语)…… 那个看似很长的式子的意义其实是逻辑左移动,就是最高位会出现在最低位的意思(这谁能看出来……).此时x取值经过那个式子后仍然可以遍历[0,2^n), O(m)枚举断点, ...
- PAN-OS 6.1 Open Source Software (OSS) Listing
https://www.paloaltonetworks.com/documentation/oss-listings/oss-listings/pan-os-oss-listings/pan-os- ...
- mysql 字段名和关键字冲突
用"(`)"将有冲突的字段框起来,,键盘上1边上那个键. 例: SELECT * FROM yun_roleright WHERE right LIKE '%{13}%'; 上面s ...
- c++第一次的个人作业
循环结构是c++中重要的结构用以实现代码的反复使用 三种不同的循环结构以及嵌套是必须认识与能够使用的 三种循环结构分别是: 在for循环中可以在for后的括号内加入初始条件,循环条件与参数变化.使得整 ...
- hdu 1789 Doing Homework again (Greedy)
Problem - 1789 继续贪心.经典贪心算法,如果数据比较大就要用线段树来维护了. 思路很简单,只要按照代价由大到小排序,然后靠后插入即可.RE了一次,是没想到deadline可以很大.如果d ...
- EF CodeFirst 实例Demo
一直想搞一个EFCodeFirst的Demo,让自己通过实例真正了解CodeFirst,方便以后有需求的时候可以有思路.网上查了很多资料,发现很多博主的文章大量重复,根据推荐步骤走并不一定能够成功,而 ...
- python中break和continue的区别
python中break和continue的区别 break和continue 1.break 意思为结束循环 例: i = 0 while i<10: i+=1 if ...
- laravel validate 设置为中文(验证提示为中文)
把 resources\lang 下en 的文件夹 复制在同一目录并改名为 zn 把zn 中的 validation.php文件修改为 https://laravel-china.org/articl ...
- 【CSS3动画】下拉菜单模拟
下拉菜单模拟效果图: CSS3: <style> #box{width:200px; height:50px; overflow:hidden; cursor: pointer; tran ...
- 2015-2016 ACM-ICPC Southwestern Europe Regional Contest (SWERC 15)
C. Canvas Painting 合并果子. E. Wooden Signs \(dp(i,l,r)\)表示第\(i\)块木板的长度区间为\([l,r]\)的方案数,根据题意,\(l\)或\(r\ ...