BZOJ 4504: K个串
题目大意:
求一个序列的第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个串的更多相关文章
- bzoj : 4504: K个串 区间修改主席树
4504: K个串 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 268 Solved: 110[Submit][Status][Discuss] ...
- bzoj 4504: K个串 可持久化线段树+堆
题目: Description 兔子们在玩k个串的游戏.首先,它们拿出了一个长度为n的数字序列,选出其中的一 个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计一次). 兔子们想 ...
- bzoj 4504: K个串【大根堆+主席树】
像超级钢琴一样把五元组放进大根堆,每次取一个出来拆开,(d,l,r,p,v)表示右端点为d,左端点区间为(l,r),最大区间和值为v左端点在p上 关于怎么快速求区间和,用可持久化线段树维护(主席树?) ...
- [bzoj P4504] K个串
[bzoj P4504] K个串 [题目描述] 兔子们在玩k个串的游戏.首先,它们拿出了一个长度为n的数字序列,选出其中的一个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计一次 ...
- bzoj4504 k个串 kstring 可持久化线段树 (标记永久化)
[fjwc2015]k个串 kstring [题目描述] 兔子们在玩k个串的游戏.首先,它们拿出了一个长度为n的数字序列,选出其中的一个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只 ...
- 数据结构(主席树):COGS 2213. K个串
2213. K个串 ★★★★ 输入文件:bzoj_4504.in 输出文件:bzoj_4504.out 简单对比时间限制:20 s 内存限制:512 MB [题目描述] 兔子们在玩k个 ...
- BZOJ 3110 K大数查询 | 整体二分
BZOJ 3110 K大数查询 题面 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个 ...
- 问题 K: 周期串plus
问题 K: 周期串plus 时间限制: 1 Sec 内存限制: 128 MB提交: 682 解决: 237[提交] [状态] [命题人:外部导入] 题目描述 如果一个字符串可以由某个长度为k的字符 ...
- hiho#1449 重复旋律6 求长度为k的串最大次数 后缀自动机
题目传送门 题目大意:求长度为k的串的最大次数,把k从1到length的所有答案全部输出. 思路: 这道题放在$SAM$里就是求长度$k$对应的所有$right$集中最大的大小. 我们以$aabab$ ...
随机推荐
- python入门之迭代器
迭代器 已知,可以直接作用于for循环的数据类型有: 一类是集合数据类型,如list.tuple.dict.set.str 一类是generator,包括生成器和带yield的generator fu ...
- [译]Understanding ECMAScript6 迭代器与生成器(未完)
迭代器在许多编程语言中被作为一种更易处理数据集合的方式被使用.在ECMAScript6中,JavaScript添加了迭代器,将其作为此语言的一个重要特征.当再加上新的方法和新的集合类型(比如集合与映射 ...
- 获取span里面的值(特殊情况下 )
如何获取A? <div class="warpper"> <span class="content"> A <span>12 ...
- 初学者应该怎么学习前端?web前端的发展路线大剖析!
写在最前: 优秀的Web前端开发工程师要在知识体系上既要有广度和深度!应该具备快速学习能力. 前端开发工程师不仅要掌握基本的Web前端开发技术,网站性能优化.SEO和服务器端的基础知识,而且要学会运用 ...
- Android属性系统简介
1.简介 在android 系统中,为统一管理系统的属性,设计了一个统一的属性系统.每个属性都有一个名称和值,他们都是字符串格式.属性被大量使用在Android系统中,用来记录系统设置或进程之间的信息 ...
- Volley源码解析(三) 有缓存机制的情况走缓存请求的源码分析
Volley源码解析(三) 有缓存机制的情况走缓存请求的源码分析 Volley之所以高效好用,一个在于请求重试策略,一个就在于请求结果缓存. 通过上一篇文章http://www.cnblogs.com ...
- 【进度总结】第一个web应用程序(未完成)
web程序快速导航 使用Eclipse for Java EE Web Development,并配置Tomcat,这部分内容在众多教程中都描述的十分详细.我直接从代码部分开始记录流程: 这张图是We ...
- uvm_factory——我们的工厂(三)
现在让我们回过头来想想factory 是用来干什么,它做了什么? fantory就是生产uvm_object 和 uvm_component.用factory 生产和用SV直接new有什么区别了? f ...
- LR中下载文件的脚本
#include "web_api.h" Action(){ int iflen; //文件大小 long lfbody; //响应数据内容大小 web_url("xxx ...
- MFC技术积累——基于MFC对话框类的那些事儿
1. 创建对话框类 (1)打开VC++6.0环境,点击:文件→新建: (2)在弹出的新建对话框中选择:工程→MFC AppWizard (exe)→输入工程名称(例如:功能调试)→工程保存路径名→确定 ...