题意:一个长度为n的数字序列,选出其中的一个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计一次)询问第k大的和是多少

1 <= n <= 100000, 1 <= k <= 200000, 0 <= a[i]<= 10^9

思路:类似于超级钢琴的思路

对于每一个右端点建立一棵主席树维护左端点的最大值

对于a[i]它对[last[a[i]]+1,i]有a[i]的贡献

再维护一个堆维护全局最大值

删除的时候就找到最大值的位置赋值成最小值

C++ STL 不会用 好烦

 #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<queue>
#include<stack>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef vector<int> VI;
#define fi first
#define se second
#define MP make_pair
#define N 21000000
#define M 110000
#define eps 1e-8
#define pi acos(-1)
#define oo 1e18
#define MOD 10007 struct node
{
ll v;
int id;
node()
{
}
node(ll V,int P)
{
v=V; id=P;
}
friend bool operator <(node x,node y)
{
return x.v<y.v;
}
}; struct tree
{
int l,r;
ll a,s;
}t[N]; priority_queue<node>q;
map<int,int>last;
int a[M],root[M],n,cnt; void pushup(int p)
{
t[p].s=;
if(!t[p].r) t[p].s=t[t[p].l].s;
else if(!t[p].l) t[p].s=t[t[p].r].s;
else t[p].s=max(t[t[p].l].s,t[t[p].r].s);
t[p].s+=t[p].a;
} void update(int l,int r,int x,int y,int v,int &r1,int r2)
{
r1=++cnt;
t[r1]=t[r2];
if(x<=l&&r<=y)
{
t[r1].a+=v;
pushup(r1);
return;
}
int mid=(l+r)>>;
if(x<=mid) update(l,mid,x,y,v,t[r1].l,t[r2].l);
if(y>mid) update(mid+,r,x,y,v,t[r1].r,t[r2].r);
pushup(r1);
} void del(int l,int r,int &p)
{
int x=p;
p=++cnt;
t[cnt]=t[x];
if(l==r)
{
t[p].a=-oo;
pushup(p);
return;
}
int mid=(l+r)>>;
if(!t[p].r) del(l,mid,t[p].l);
else if(!t[p].l) del(mid+,r,t[p].r);
else
{
if(t[t[p].l].s>=t[t[p].r].s) del(l,mid,t[p].l);
else del(mid+,r,t[p].r);
}
pushup(p);
} int main()
{
//freopen("bzoj4504.in","r",stdin);
//freopen("bzoj4504.out","w",stdout);
int k;
scanf("%d%d",&n,&k);
cnt=;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
update(,n,i,i,,root[i],root[i-]);
update(,n,last[a[i]]+,i,a[i],root[i],root[i]);
last[a[i]]=i;
q.push(node(t[root[i]].s,i));
}
for(int i=;i<k;i++)
{
int x=q.top().id;
q.pop();
del(,n,root[x]);
q.push(node(t[root[x]].s,x));
}
printf("%lld\n",q.top().v);
return ;
}

【BZOJ4504&&Hihocoder1046】K个串(主席树,堆)的更多相关文章

  1. 【BZOJ4504】K个串 可持久化线段树+堆

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

  2. bzoj 4504: K个串【大根堆+主席树】

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

  3. spoj COT - Count on a tree (树上第K小 LCA+主席树)

    链接: https://www.spoj.com/problems/COT/en/ 思路: 首先看到求两点之前的第k小很容易想到用主席树去写,但是主席树处理的是线性结构,而这道题要求的是树形结构,我们 ...

  4. [luogu3834]静态区间第k小【主席树】

    传送门:https://www.luogu.org/problemnew/show/P3834 题目描述 如题,给定N个整数构成的序列,将对于指定的闭区间查询其区间内的第K小值. 分析 很多人都说是用 ...

  5. Dynamic Rankings || 动态/静态区间第k小(主席树)

    JYF大佬说,一星期要写很多篇博客才会有人看 但是我做题没有那么快啊QwQ Part1 写在前面 区间第K小问题一直是主席树经典题=w=今天的重点是动态区间第K小问题.静态问题要求查询一个区间内的第k ...

  6. POJ 2104 && POJ 2761 (静态区间第k大,主席树)

    查询区间第K大,而且没有修改. 使用划分树是可以做的. 作为主席树的入门题,感觉太神奇了,Orz /* *********************************************** ...

  7. zoj2112 主席树动态第k大 (主席树&&树状数组)

    Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has ...

  8. 静态区间第k大(主席树)

    POJ 2104为例(主席树入门题) 思想: 可持久化线段树,也叫作函数式线段树,也叫主席树(高大上). 可持久化数据结构(Persistent data structure):利用函数式编程的思想使 ...

  9. POJ 2104 K-th Number ( 求取区间 K 大值 || 主席树 || 离线线段树)

    题意 : 给出一个含有 N 个数的序列,然后有 M 次问询,每次问询包含 ( L, R, K ) 要求你给出 L 到 R 这个区间的第 K 大是几 分析 : 求取区间 K 大值是个经典的问题,可以使用 ...

  10. poj2104 K-th Number区间第k小值 主席树

    原来主席树就是可持久化线段树啊,刚知道,,, 作为一道裸题,还是必A的,然而一开始偷懒不写离散化跪了N多遍,后来在缪大的帮助下发现了这个问题,遂A之 ——又是这种破问题,实在不想说自己了 把n个数看成 ...

随机推荐

  1. Express框架 --router/app.use

    翻看去年自己记录的印象笔记,准备把笔记上的一些内容也同时更新到博客上,方便自己查看. 1.app.use和app.get的区别及解析 app.use(path,callback)中的callback既 ...

  2. SummerVocation_Learning--java的多线程实现

    java的线程是通过java.lang.Thread类来实现的. 可以通过创建Thread的实例来创建新的线程. 每个线程都是通过某个特定Thread对象所对应的方法run()来完成操作,方法run( ...

  3. Windows 下编辑 hosts 文件

    hosts 文件目录: C:\WINDOWS\system32\drivers\etc\hosts hosts是一个没有扩展名的系统文件,可以用记事本等工具打开,其作用就是将一些常用的网址域名与其对应 ...

  4. 爬取代理IP,并判断是否可用。

    # -*- coding:utf-8 -*- from gevent import monkey monkey.patch_all() import urllib2 from gevent.pool ...

  5. Shell脚本使用汇总整理——mysql数据库5.7.8以后备份脚本

    Shell脚本使用汇总整理——mysql数据库5.7.8以后备份脚本 Shell脚本使用的基本知识点汇总详情见连接: https://www.cnblogs.com/lsy-blogs/p/92234 ...

  6. tp5.1发送邮件

    <?php namespace app\admin\controller; use think\Controller; use think\Request; use PHPMailer\PHPM ...

  7. tcl之list操作-llength/lindex/lrange/linsert/lreplace

  8. windows下软件安装目录

    说明:该软件目录为自身在实际学习开发中系统下安装的目录,方便自己的查看以及和他人交流,如有软件需要,请留言,谢谢! 1) PADSVX.1.2 中级PCB绘图软件! 2) Caendece 17.2 ...

  9. collections模块简介

    collections模块简介 除python提供的内置数据类型(int.float.str.list.tuple.dict)外,collections模块还提供了其他数据类型,使用如下功能需先导入c ...

  10. redis配置密码 redis常用命令

    redis配置密码 1.通过配置文件进行配置yum方式安装的redis配置文件通常在/etc/redis.conf中,打开配置文件找到 [plain] view plain copy   #requi ...