题目大意:

求一个序列的第k大的子串和。

题解:

对于一个右端点找最优的左端点,扔进堆里。

每次取堆顶,将这个右端点可以选择的左端点的区间分成两段,扔进堆里,重复k次。

现在需要对于一个固定的右端点,左端点在一个区间里,求最大值。

可持久化线段树上区间修改,不用标记永久化也可以过。

代码:

#include<cstdio>
#include<algorithm>
#include<map>
#include<queue>
#define mp make_pair
#define pr pair<long long,int>
#define prr pair<pr,pr>
#define fr first
#define sc second
using namespace std;
int n,k,cnt,ls[10000005],rs[10000005],root[200005];
long long tag[10000005];
priority_queue<prr> q;
map<int,int> pre;
struct node{
long long val;
int id;
}tree[10000005];
void build(int &x,int l,int r){
x=++cnt;
tree[x]=(node){0,l};
if (l==r) return;
int mid=(l+r)>>1;
build(ls[x],l,mid);
build(rs[x],mid+1,r);
}
void add(int &now,int pre,long long key){
now=++cnt;
ls[now]=ls[pre],rs[now]=rs[pre],tree[now]=tree[pre],tag[now]=tag[pre]+key;
tree[now].val+=key;
}
void push_down(int x){
if (!tag[x]) return;
add(ls[x],ls[x],tag[x]);
add(rs[x],rs[x],tag[x]);
tag[x]=0;
}
void insert(int &now,int pre,int l,int r,int x,int y,int key){
if (l>y || r<x) return;
if (l>=x && r<=y){
add(now,pre,key);
return;
}
push_down(pre);
now=++cnt;
ls[now]=ls[pre],rs[now]=rs[pre],tree[now]=tree[pre];
int mid=(l+r)>>1;
insert(ls[now],ls[pre],l,mid,x,y,key);
insert(rs[now],rs[pre],mid+1,r,x,y,key);
if (tree[rs[now]].val>tree[ls[now]].val) tree[now]=tree[rs[now]];
else tree[now]=tree[ls[now]];
}
node query(int now,int l,int r,int x,int y){
if (!now) return (node){-1ll<<60,0};
if (l>y || r<x) return (node){-1ll<<60,0};
if (l>=x && r<=y) return tree[now];
push_down(now);
int mid=(l+r)>>1;
node max1=query(ls[now],l,mid,x,y);
node max2=query(rs[now],mid+1,r,x,y);
if (max1.val>max2.val) return max1;
else return max2;
}
void insert(int x,int l,int r){
if (l>r) return;
node sum=query(x,1,n,l,r);
q.push(mp(mp(sum.val,x),mp(l,r)));
}
int main(){
scanf("%d%d",&n,&k);
build(root[0],1,n);
for (int i=1; i<=n; i++){
int x;
scanf("%d",&x);
insert(root[i],root[i-1],1,n,pre[x]+1,i,x);
pre[x]=i;
insert(root[i],1,i);
}
long long sum;
while (k--){
sum=q.top().fr.fr;
int id=q.top().fr.sc,l=q.top().sc.fr,r=q.top().sc.sc;
q.pop();
int mid=query(id,1,n,l,r).id;
insert(id,l,mid-1);
insert(id,mid+1,r);
}
printf("%lld\n",sum);
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个串【大根堆+主席树】

    像超级钢琴一样把五元组放进大根堆,每次取一个出来拆开,(d,l,r,p,v)表示右端点为d,左端点区间为(l,r),最大区间和值为v左端点在p上 关于怎么快速求区间和,用可持久化线段树维护(主席树?) ...

  4. [bzoj P4504] K个串

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

  5. bzoj4504 k个串 kstring 可持久化线段树 (标记永久化)

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

  6. 数据结构(主席树):COGS 2213. K个串

    2213. K个串 ★★★★   输入文件:bzoj_4504.in   输出文件:bzoj_4504.out   简单对比时间限制:20 s   内存限制:512 MB [题目描述] 兔子们在玩k个 ...

  7. BZOJ 3110 K大数查询 | 整体二分

    BZOJ 3110 K大数查询 题面 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个 ...

  8. 问题 K: 周期串plus

    问题 K: 周期串plus 时间限制: 1 Sec  内存限制: 128 MB提交: 682  解决: 237[提交] [状态] [命题人:外部导入] 题目描述 如果一个字符串可以由某个长度为k的字符 ...

  9. hiho#1449 重复旋律6 求长度为k的串最大次数 后缀自动机

    题目传送门 题目大意:求长度为k的串的最大次数,把k从1到length的所有答案全部输出. 思路: 这道题放在$SAM$里就是求长度$k$对应的所有$right$集中最大的大小. 我们以$aabab$ ...

随机推荐

  1. 关于vue的源码调试

    一直看源码都是硬生生的看, 其实, 还是感觉调试起来会看的比较舒服. GitHub把vue的源码下载下来 npm install && npm run dev 在example中新建一 ...

  2. Hive_Hive的安装

    嵌入模式不推荐使用. 本地模式多用于开发和测试. 远程模式多用于生产环境.

  3. vue 引用其他组件

    1.在components 目录下新建Test.vue 文件 <template> <div class="test"> <h1>{{ msg ...

  4. VC运行时库(/MD、/MT等)

    VC项目属性→配置属性→C/C++→代码生成→运行时库 可以采用的方式有:多线程(/MT).多线程调试(/MTd).多线程DLL(/MD).多线程调试DLL(/MDd).单线程(/ML).单线程调试( ...

  5. siege4安装和使用介绍

    使用文档参考地址:https://www.joedog.org/siege-manual/ siege4地址:http://download.joedog.org/siege/ cd /usr/loc ...

  6. java代码(生成日历时间)

    package test; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; p ...

  7. 100行代码让您学会JavaScript原生的Proxy设计模式

    面向对象设计里的设计模式之Proxy(代理)模式,相信很多朋友已经很熟悉了.比如我之前写过代理模式在Java中实现的两篇文章: Java代理设计模式(Proxy)的四种具体实现:静态代理和动态代理 J ...

  8. 在Windows笔记本上调试运行在iOS设备上的前端应用

    我在每天工作中需要在不同的移动设备上测试我们开发的前端应用是否正常工作,比如iOS设备和Android设备.我用的工作笔记本电脑又是Lenovo的,安装的是Windows操作系统. 有的时候一个开发好 ...

  9. Solr版本安装部署指南

    一.依赖包 1.  JDK 1.6以上 2.  solr-4.3.0.tgz 3.  Tomcat或者jetty(注意,solr包中本身就含有jetty的启动相关内容):apache-tomcat-7 ...

  10. jni 开发

    创建android工程 -> 添加native 函数 添加库之后: 1. 用javah 生成c语言.h头文件时, 在cmd 窗口中cd 到bin/classes 目录下执行下代码无效: java ...