【BZOJ4504】K个串

Description

兔子们在玩k个串的游戏。首先,它们拿出了一个长度为n的数字序列,选出其中的一个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计一次)。兔子们想知道,在这个数字序列所有连续的子串中,按照以上方式统计其所有数字之和,第k大的和是多少。

Input

第一行,两个整数n和k,分别表示长度为n的数字序列和想要统计的第k大的和
接下里一行n个数a_i,表示这个数字序列

Output

一行一个整数,表示第k大的和

Sample Input

7 5
3 -2 1 2 2 1 3 -2

Sample Output

4

HINT

1 <= n <= 100000, 1 <= k <= 200000, 0 <= |a_i| <= 10^9数据保证存在第 k 大的和

题解:沿用超级钢琴的思路。用堆维护五元组(x,a,b,y,val)表示右端点为x,左端点在[a,b]中,最优的左端点是y,且y到x的和是val。然后每次从优先队列中取出val最大的,将其删去,在[a,y)和(y,b]中分别寻找新的y,然后将其扔回到队列中去。

问题是如何找y呢?考虑可持久化线段树。因为每个区间都是某个前缀的后缀,所以如果当前的右端点是x,x的前驱是pre[x],我们只需要在x的线段树中将(pre[x],x]的权值都加上val[x]即可。可以用标记永久化来加速主席树的区间修改。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
using namespace std;
const int maxn=100010;
typedef long long ll;
int n,m,tot;
ll v[maxn];
int rt[maxn],pre[maxn];
map<ll,int> last;
struct node
{
int l,r,x,y;
ll v;
node() {}
node(int a,int b,int c,ll d,int e) {x=a,l=b,r=c,v=d,y=e;}
bool operator < (const node &a) const {return v<a.v;}
};
struct sag
{
ll x; int y;
sag() {x=-1ll<<60,y=0;}
}s[maxn*100];
int ls[maxn*100],rs[maxn*100];
ll tag[maxn*100];
priority_queue<node> q;
sag operator + (const sag &a,const sag &b)
{
return ((a.x==b.x)?(a.y>b.y):(a.x>b.x))?a:b;
}
void build(int l,int r,int &x)
{
x=++tot,s[x].x=0,s[x].y=l;
if(l==r) return ;
int mid=(l+r)>>1;
build(l,mid,ls[x]),build(mid+1,r,rs[x]);
}
void insert(int x,int &y,int l,int r,int a,int b,ll c)
{
y=++tot,s[y]=s[x],ls[y]=ls[x],rs[y]=rs[x],tag[y]=tag[x];
if(a<=l&&r<=b)
{
s[y].x+=c,tag[y]+=c;
return ;
}
int mid=(l+r)>>1;
if(a<=mid) insert(ls[x],ls[y],l,mid,a,b,c);
if(b>mid) insert(rs[x],rs[y],mid+1,r,a,b,c);
s[y]=s[ls[y]]+s[rs[y]];
s[y].x+=tag[y];
}
sag query(int l,int r,int x,int a,int b)
{
if(a<=l&&r<=b) return s[x];
int mid=(l+r)>>1;
sag ret;
ret.y=l;
if(a<=mid) ret=ret+query(l,mid,ls[x],a,b);
if(b>mid) ret=ret+query(mid+1,r,rs[x],a,b);
ret.x+=tag[x];
return ret;
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int main()
{
n=rd(),m=rd();
int i,a,b,x;
ll y;
sag t;
node u;
build(1,n,rt[0]);
for(i=1;i<=n;i++)
{
v[i]=rd(),pre[i]=last[v[i]],last[v[i]]=i;
insert(rt[i-1],rt[i],1,n,pre[i]+1,i,v[i]);
t=query(1,n,rt[i],1,i);
q.push(node(i,1,i,t.x,t.y));
}
while(m--)
{
u=q.top(),q.pop();
x=u.x,a=u.l,b=u.r,y=u.y;
if(!m)
{
printf("%lld\n",u.v);
return 0;
}
if(a<y)
{
t=query(1,n,rt[x],a,y-1);
q.push(node(x,a,y-1,t.x,t.y));
}
if(b>y)
{
t=query(1,n,rt[x],y+1,b);
q.push(node(x,y+1,b,t.x,t.y));
}
}
return 0;
}//8 5 3 -2 1 2 2 1 3 -2

【BZOJ4504】K个串 可持久化线段树+堆的更多相关文章

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

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

  2. hihocoder#1046 K个串 可持久化线段树 + 堆

    首先考虑二分,然后发现不可行.... 注意到\(k\)十分小,尝试从这里突破 首先用扫描线来处理出以每个节点为右端点的区间的权值和,用可持久化线段树存下来 在所有的右端点相同的区间中,挑一个权值最大的 ...

  3. SPOJ-COT-Count on a tree(树上路径第K小,可持久化线段树)

    题意: 求树上A,B两点路径上第K小的数 分析: 同样是可持久化线段树,只是这一次我们用它来维护树上的信息. 我们之前已经知道,可持久化线段树实际上是维护的一个前缀和,而前缀和不一定要出现在一个线性表 ...

  4. [POJ2104] 区间第k大数 [区间第k大数,可持久化线段树模板题]

    可持久化线段树模板题. #include <iostream> #include <algorithm> #include <cstdio> #include &l ...

  5. 树上第k小,可持久化线段树+倍增lca

    给定一颗树,树的每个结点都有权值, 有q个询问,每个询问是 u v k ,表示u到v路径上第k小的权值是多少. 每个结点所表示的线段树,是父亲结点的线段树添加该结点的权值之后形成的新的线段树 c[ro ...

  6. [POJ2104] K – th Number (可持久化线段树 主席树)

    题目背景 这是个非常经典的主席树入门题--静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个正整数构成的序列,将对于指定的闭区间查询其区间内的第K小值. 输入输 ...

  7. HDU 2665.Kth number-可持久化线段树(无修改区间第K小)模板 (POJ 2104.K-th Number 、洛谷 P3834 【模板】可持久化线段树 1(主席树)只是输入格式不一样,其他几乎都一样的)

    Kth number Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  8. POJ- 2104 hdu 2665 (区间第k小 可持久化线段树)

    可持久化线段树 也叫函数式线段树也叫主席树,其主要思想是充分利用历史信息,共用空间 http://blog.sina.com.cn/s/blog_4a0c4e5d0101c8fr.html 这个博客总 ...

  9. 主席树(可持久化线段树) 静态第k大

    可持久化数据结构介绍 可持久化数据结构是保存数据结构修改的每一个历史版本,新版本与旧版本相比,修改了某个区域,但是大多数的区域是没有改变的, 所以可以将新版本相对于旧版本未修改的区域指向旧版本的该区域 ...

随机推荐

  1. 物联网通信协议——比较-MQTT、 DDS、 AMQP、XMPP、 JMS、 REST、 CoAP

    物联网通信协议——比较-MQTT. DDS. AMQP.XMPP. JMS. REST. CoAP   AMQP & MQTT & DDS (https://www.youtube.c ...

  2. openssl 创建证书的总结和注意事项

    1.该文章从网上看了好多博客,并经过实践形成.环境为ubuntu12和ubuntu14 "========================================大纲提要和注意事项= ...

  3. TI博客文章-4-20mA电流环路发送器入门

    TI博客文章-4-20mA电流环路发送器入门http://bbs.21ic.com/forum.php?mod=viewthread&tid=1610834&fromuid=10995 ...

  4. atitit.it企业管理 项目管理 中的 授权机制 的来源 君权神授 的一定合理性

    atitit.it企业管理 项目管理 中的 授权机制 的来源 君权神授 的一定合理性 1. 授权(权利来源)的5种模式 1 2. 企业的组织机构与管理运作来源于国家的管理...而国家的管理又来源于宗教 ...

  5. [k8s]k8s架构图解

    k8s架构图解 启动参数及证书梳理 master端必须要装flannel 注: flannel网络能确保各节点间 Pod 网段实现互通 master 节点与 node 节点上的 Pods 通过 Pod ...

  6. 关于阿里云ECS Centos 5/6/7 Linux Glibc库严重安全漏洞修复方法

    日前Linux GNU glibc标准库的 gethostbyname函数爆出缓冲区溢出漏洞,漏洞编号为CVE-2015-0235.黑客可以通过gethostbyname系列函数实现远程代码执行,获取 ...

  7. 选择如何的系统更能适合App软件开发人员?

    手机这个词早已经同吃喝玩乐一样.成为了人们生活中的必备元素. 尤其是iPhone一炮走红之后,不但手机世界发生了巨大变化,整个科技产业似乎都格局性的改变.直至今日,手机市场的竞争更是日趋白炽化,这就给 ...

  8. iOS开发 -李洪强-清除缓存

    // //  SetViewController.m //  dfhx // //  Created by dfhx_iMac_001 on 16/4/5. //  Copyright © 2016年 ...

  9. Android Screen Monitor

    实现屏幕同步前提是安装有JDK和配置好ADB的环境变量 1.官方地址 http://code.google.com/p/android-screen-monitor/ 2.解压缩得到asm.jar 3 ...

  10. 写一个php小脚本辅助渗透测试

    因为一个注入要爬行一些数据,然后写的一个小脚本,能写脚本来辅助渗透,也算是里程碑.哈哈哈 <?php $num = 1; while ($num <= 39) { $web_url = & ...