像超级钢琴一样把五元组放进大根堆,每次取一个出来拆开,(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. Android中View绘制流程以及invalidate()等相关方法分析(转)

    转自:http://blog.csdn.net/qinjuning 前言: 本文是我读<Android内核剖析>第13章----View工作原理总结而成的,在此膜拜下作者 .同时真挚地向渴 ...

  2. Node.js机制及原理理解初步

    http://blog.csdn.net/leftfist/article/details/41891407 一.node.js优缺点 node.js是单线程. 好处就是 1)简单 2)高性能,避免了 ...

  3. TestNG – Dependency Test

    转自:http://www.mkyong.com/unittest/testng-tutorial-7-dependency-test/ In TestNG, we use dependOnMetho ...

  4. An O(ND) Difference Algorithm and Its Variations (1986)

    http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927 The problems of finding a longest com ...

  5. Struts2的工作原理(图解)详解

    Struts2的工作原理 上图来源于Struts2官方站点,是Struts 2 的整体结构. 一个请求在Struts2框架中的处理大概分为以下几个步骤(可查看源码:https://github.com ...

  6. HDU 6118 度度熊的交易计划 【最小费用最大流】 (2017"百度之星"程序设计大赛 - 初赛(B))

    度度熊的交易计划 Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  7. Mac开发必备工具(一)—— Homebrew

    Homebrew 简介 macOS 缺失的软件包管理器.使用 Homebrew 安装 Apple 没有预装但 你需要的东西.官网有中文说明. 安装与配置 Homebrew 的安装非常简单,将下面这条命 ...

  8. seafile看不见repo报500错误的解决方法

    环境 seafile-server-6.2.5 centos7.5 1804 现象 seafile服务器所在的VPS没动过,前一天seafile用还好好的,昨天客户端突然不能登录了,显示“服务器内部错 ...

  9. 关于LAMP配置Let’s Encrypt SSL证书

    昨天建站,买VPS,先装了LAMP,部署wordpress,测试OK了,然后才买的域名,申请SSL证书. 结果Let’s Encrypt cerbot申请证书遇到了麻烦,--apache参数怎么也识别 ...

  10. JS中的存储机制

    一.堆和栈的介绍 1.堆和队,是先进先出:栈,是先进后出,就跟水桶差不多: 2.存储速度:堆和队的存储速度较慢,栈的存储速度较快,会自动释放: 二.js中存储的类型 1.堆,一般用于复杂数据类型,存储 ...