像超级钢琴一样把五元组放进大根堆,每次取一个出来拆开,(d,l,r,p,v)表示右端点为d,左端点区间为(l,r),最大区间和值为v左端点在p上

关于怎么快速求区间和,用可持久化线段树维护(主席树?)每个点到他root的区间和,这样每次右端点右移就是上一个的线段树在(la[a[i]]+1,i)加上a[i],la是这个值a[i]上一次出现的位置

然后就可以在线处理询问了

有一点因为这个线段树建的是1~n,所以右端点不是n的时候取max会取到右端点向右还是初始值0的位置(有可能前面是负数),这样的解决方法就是先全填成-inf,然后每次右移的时候先把右端点加上inf再处理区间加

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;
const int N=300005;
int n,m,has,rt[N],tot,la[N];
long long a[N],g[N],rl[N],ans;
map<long long ,int>mp;
struct zxs
{
int ls,rs,p;
long long mx,lz;
}t[7000005];
struct qwe
{
int d,l,r,p;
long long v;
qwe(int D=0,int L=0,int R=0,int P=0,long long V=0)
{
d=D,l=L,r=R,p=P,v=V;
}
bool operator < (const qwe &a) const
{
return v<a.v;
}
};
priority_queue<qwe>q;
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
void build(int &ro,int l,int r)
{
ro=++tot;
t[ro].p=l,t[ro].mx=-1e15;
if(l==r)
return;
int mid=(l+r)>>1;
build(t[ro].ls,l,mid);
build(t[ro].rs,mid+1,r);
}
void ud(int ro)
{
if(t[t[ro].ls].mx>t[t[ro].rs].mx)
t[ro].mx=t[t[ro].ls].mx,t[ro].p=t[t[ro].ls].p;
else
t[ro].mx=t[t[ro].rs].mx,t[ro].p=t[t[ro].rs].p;
}
void update(int &ro,int la,int l,int r,int ll,int rr,long long v,long long lz)
{
ro=++tot;
t[ro]=t[la];
t[ro].lz+=lz;
t[ro].mx+=lz;
if(l==ll&&r==rr)
{
t[ro].lz+=v;
t[ro].mx+=v;
return;
}
int mid=(l+r)>>1;
if(t[ro].lz)
{
if(rr<=mid)
{
t[ro].rs=++tot;
t[t[ro].rs]=t[t[la].rs];
t[t[ro].rs].mx+=t[ro].lz;
t[t[ro].rs].lz+=t[ro].lz;
update(t[ro].ls,t[la].ls,l,mid,ll,rr,v,t[ro].lz);
}
else if(ll>mid)
{
t[ro].ls=++tot;
t[t[ro].ls]=t[t[la].ls];
t[t[ro].ls].mx+=t[ro].lz;
t[t[ro].ls].lz+=t[ro].lz;
update(t[ro].rs,t[la].rs,mid+1,r,ll,rr,v,t[ro].lz);
}
else
{
update(t[ro].ls,t[la].ls,l,mid,ll,mid,v,t[ro].lz);
update(t[ro].rs,t[la].rs,mid+1,r,mid+1,rr,v,t[ro].lz);
}
t[ro].lz=0;
}
else
{
if(rr<=mid)
update(t[ro].ls,t[la].ls,l,mid,ll,rr,v,0);
else if(ll>mid)
update(t[ro].rs,t[la].rs,mid+1,r,ll,rr,v,0);
else
{
update(t[ro].ls,t[la].ls,l,mid,ll,mid,v,0);
update(t[ro].rs,t[la].rs,mid+1,r,mid+1,rr,v,0);
}
}
ud(ro);
}
pair<long long,int> ques(int ro,int l,int r,int ll,int rr)
{//cerr<<l<<" "<<r<<" "<<ll<<" "<<rr<<endl;
if(l==ll&&r==rr)
return make_pair(t[ro].mx,t[ro].p);
if(t[ro].lz)
{
t[tot+1]=t[t[ro].ls];
t[tot+1].mx+=t[ro].lz;
t[tot+1].lz+=t[ro].lz;
t[ro].ls=tot+1;
t[tot+2]=t[t[ro].rs];
t[tot+2].mx+=t[ro].lz;
t[tot+2].lz+=t[ro].lz;
t[ro].rs=tot+2;
tot+=2;
t[ro].lz=0;
}
int mid=(l+r)>>1;
if(rr<=mid)
return ques(t[ro].ls,l,mid,ll,rr);
else if(ll>mid)
return ques(t[ro].rs,mid+1,r,ll,rr);
else
{
pair<long long,int>a=ques(t[ro].ls,l,mid,ll,mid),b=ques(t[ro].rs,mid+1,r,mid+1,rr);
return (a.first>b.first)?a:b;
}
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++)
a[i]=g[i]=read();
sort(g+1,g+1+n);
for(int i=1;i<=n;i++)
if(i==1||g[i]!=g[i-1])
mp[g[i]]=++has,rl[has]=g[i];
build(rt[0],1,n);
for(int i=1;i<=n;i++)
{
update(rt[i],rt[i-1],1,n,i,i,1e15,0);
update(rt[i],rt[i],1,n,la[mp[a[i]]]+1,i,a[i],0);
la[mp[a[i]]]=i;//cerr<<"OK"<<endl;
}
for(int i=1;i<=n;i++)
q.push(qwe(i,1,i,t[rt[i]].p,t[rt[i]].mx));
while(m--)
{
qwe u=q.top();
q.pop();
ans=u.v;//cerr<<ans<<endl;
if(u.l<=u.p-1)
{
pair<long long,int>nw=ques(rt[u.d],1,n,u.l,u.p-1);
q.push(qwe(u.d,u.l,u.p-1,nw.second,nw.first));
}
if(u.p+1<=u.r)
{
pair<long long,int>nw=ques(rt[u.d],1,n,u.p+1,u.r);
q.push(qwe(u.d,u.p+1,u.r,nw.second,nw.first));
}
}
printf("%lld\n",ans);
return 0;
}

bzoj 4504: K个串【大根堆+主席树】的更多相关文章

  1. bzoj : 4504: K个串 区间修改主席树

    4504: K个串 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 268  Solved: 110[Submit][Status][Discuss] ...

  2. bzoj 4504: K个串 可持久化线段树+堆

    题目: Description 兔子们在玩k个串的游戏.首先,它们拿出了一个长度为n的数字序列,选出其中的一 个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计一次). 兔子们想 ...

  3. BZOJ 4504: K个串

    题目大意: 求一个序列的第k大的子串和. 题解: 对于一个右端点找最优的左端点,扔进堆里. 每次取堆顶,将这个右端点可以选择的左端点的区间分成两段,扔进堆里,重复k次. 现在需要对于一个固定的右端点, ...

  4. [bzoj P4504] K个串

    [bzoj P4504] K个串 [题目描述] 兔子们在玩k个串的游戏.首先,它们拿出了一个长度为n的数字序列,选出其中的一个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计一次 ...

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

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

  6. BZOJ 2006 超级钢琴(堆+主席树)

    很好的一道题. 题意:给出长度为n的数列,选择k个互不相同的区间,满足每个区间长度在[L,R]内,求所有选择的区间和的总和最大是多少.(n,k<=5e5). 首先将区间和转化为前缀和之差,那么我 ...

  7. 【BZOJ4504】K个串 可持久化线段树+堆

    [BZOJ4504]K个串 Description 兔子们在玩k个串的游戏.首先,它们拿出了一个长度为n的数字序列,选出其中的一个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计 ...

  8. BZOJ 2006 [NOI2010]超级钢琴 (堆+主席树)

    题面:BZOJ传送门 洛谷传送门 让你求前$K$大的子序列和,$n\leq 5*10^{5}$ 只想到了个$nlog^{2}n$的做法,似乎要被卡常就看题解了.. 好神奇的操作啊,我傻了 我们把序列和 ...

  9. 51nod K 汽油补给 大根堆+小根堆....

    题目传送门 用优先队列瞎搞... 想着在每个地方 先算上一个点到这一个点要花费多少钱 这个用小根堆算就好 然后在这个地方加油 把油钱比自己多的替代掉 这个用大根堆维护一下 然后两个堆之间信息要保持互通 ...

随机推荐

  1. 【软件project】菜鸟俯瞰软件project

    [背景]初次接触软件project,对软件project不是彻底的了解.但学完一遍软件project,我还是有些感触的. 以下我就对我这阶段的软工学习和理解做一下小小的总结,如有不妥之处.欢迎指正. ...

  2. c++面试题总结(4)

    一.找错题 试题1: void test1() { ]; "; strcpy( string, str1 ); } 试题2: void test2() { ],str1[]; int i; ...

  3. 【转载】读懂IL代码就这么简单 (一)

    一前言 感谢 @冰麟轻武 指出文章的错误之处,现已更正 对于IL代码没了解之前总感觉很神奇,初一看完全不知所云,只听高手们说,了解IL代码你能更加清楚的知道你的代码是如何运行相互调用的,此言一出不明觉 ...

  4. scala进阶笔记:函数组合器(combinator)

    collection基础参见之前的博文scala快速学习(二). 本文主要是组合器(combinator),因为在实际中发现很有用.主要参考:http://www.importnew.com/3673 ...

  5. WM_GETMINMAXINFO的作用 .

    如果想要实现窗口全屏,并且还有状态栏,会出现问题,那就是OnGetMinMaxInfo函数的作用.你可以试一下,如果把这个函数去掉,则当你按下工具栏中的全屏显示按钮时,框架视图确实变大了,但没有想象的 ...

  6. Tomcat 安装与配置规范

    Tomcat 安装 演示版本:8.5.32 安装版 JDK推荐版本:jdk1.8 下载地址:https://tomcat.apache.org/download-80.cgi 安装教程 注意:tomc ...

  7. Serializable 序列化 The byte stream created is platform independent. So, the object serialized on one platform can be deserialized on a different platform.

    Java 序列化接口Serializable详解 - 火星猿类 - 博客园 http://www.cnblogs.com/tomtiantao/p/6866083.html 深入理解JAVA序列化 - ...

  8. 手游服务器php架构比较

    从swoole项目开始到现在,一直有人在问这个问题.今天来抽空讲一下它.为什么swoole非要使用纯C来写而不是PHP代码来实现,核心的原因有2点: 1. PHP无法直接调用操作系统API 如send ...

  9. DOM操作三

    1.以一个对象的x和y属性的方式返回滚动条的偏移量 function getScrollOffsets(w){ //使用指定的窗口,如果不带参数则使用当前窗口 w= w || window; //除了 ...

  10. powerdesigner 导入mysql数据库(步骤及注意点)

    参考博客 PowerDesigner中导入MYSQL数据库结构的步骤 mysql ODBC 在64位下提示找不到odbc驱动问题 PowerDesigner逆向工程导入MYSQL数据库总结