题目大意:

求一个序列的第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. rtos概要

    一 RTOS如何调试: 静态调试帮不上忙,因为嵌入式系统都是动态系统 ,要借助基于RTOS系统的可视化分析 :Micriµm 的 µC/Probe ,SEGGER 的 SystemView ,Perc ...

  2. 关于IO模拟时序(SPI)的注意事项

    原则:有硬件I2C.SPI时尽量用硬件操作,省去IO模拟繁琐的时序调试.但在内部资源不够时就要用IO模拟总线了. 关于短延时:模拟时序时是否需要延时要看MCU与device的相对速度.比如I2C如果4 ...

  3. jq中的attr和prop属性

    今天在做checkbox的全选等功能时刚开始用的是 $('input[type='checkbox']").attr("checked","true" ...

  4. (转)Unity3D中常用的数据结构总结与分析

    http://www.cnblogs.com/murongxiaopifu/p/4161648.html#array   1.几种常见的数据结构 常碰到的几种数据结构:Array,ArrayList, ...

  5. 我的NopCommerce之旅(4): 定时任务之邮件

    一.功能简介 用户购买物品生成订单后,系统将发送邮件提醒给用户 二.操作步骤 后台配置一个系统的默认发送邮箱 启动定时任务,这里包括多个任务,只需要启动邮件任务 查看邮件发送情况 三.数据库分析 [d ...

  6. handler 方法进不去,服务器上出现应用程序错误。此应用程序的当前自定义错误设置禁止远程查看

    HTTP/1.1 500 Internal Server ErrorCache-Control: privateContent-Type: text/html; charset=utf-8Server ...

  7. JS的文本框验证以及form表单的提交阻止

    js: 1.只能输入数字 只能输入数字:<input type="text" onkeyup="javascript:ReNumber(this)" /& ...

  8. 定时任务-Timer

    Timer类的全限定名 java.util.Timer java.util.Timer类的构造函数 public Timer(); public Timer(boolean isDaemon); pu ...

  9. find搜索文件系统,实时搜索

    find搜索文件系统.实时搜索 find[目录][条件][动作] [目录] 不输入目录代表当前目录 find find /etc ----------------------------------- ...

  10. SQL中的IF ELSE(CASE语句的使用)

    大家对IF ELSE语句可能都很熟悉,它是用来对过程进行控制的.在SQL的世界中CASE语句语句有类似的效果.下面简单的介绍CASE语句的用法.考虑下面的情况,假设有个user表,定义如下: CREA ...