题意:一个长度为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. springboot中加入druid对sql进行监控

    springboot作为现在十分流行的框架,简化Spring应用的初始搭建以及开发过程,现在我们就使用springboot来进行简单的web项目搭建并对项目sql进行监控. 项目的搭建就省略了,spr ...

  2. 【python学习】新手基础程序练习(二)

    Ι 继续上一节得内容,这里主要是对各种知识的理解以及如何运用. 一.执行 Python 脚本的两种方式 1.把python执行文件加到计算机的环境变量中,然后新建文件把程序写在新文件里,再通过cmd命 ...

  3. 从源码带你看懂functools的partial方法

    1.what? partial是什么, partial也叫偏函数.源码的描述是: 部分应用给定参数和关键字的新函数. New function with partial application of ...

  4. HDU:2222-Keywords Search(AC自动机模板,匹配模拟)

    Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) P ...

  5. UVA11825 Hacker's Crackdown 二进制集合+关于子集的动态规划

    题意:有N台服务器,全部服务器都直接运行着完全相同的N个任务.对于每台电脑,你都可以进行“一次”操作,使得某(自己选定)一种任务停止,且同时会使得其他和这台服务器直接相连的电脑上面相同的服务完全终止. ...

  6. Git-GIt检出

    实际上在执行重置命令的时候没有使用任何参数对所要重置的分支名进行设置,这是因为重置命名实际上所针对的是头指针HEAD.之所以没有改变HEAD的内容是因为HEAD指向了一个引用refs/heads/ma ...

  7. java中equals和==区别

    equals 方法是 java.lang.Object 类的方法. 有两种用法说明: (1)对于字符串变量来说,使用“==”和“equals()”方法比较字符串时,其比较方法不同. “==”比较两个变 ...

  8. Python高级主题:Python ABC(抽象基类)

    #抽象类实例 作用统一规范接口,降低使用复杂度.import abcclass Animal(metaclass = abc.ABCMeta): ##只能被继承,不能实例化,实例化会报错 @abc.a ...

  9. 手机端sticker布局,底部按钮在屏幕底部

    <template> <div class="product-detail-container"> <div class="detail&q ...

  10. 32、详解Android shape的使用方法(转载)

    0.java绘制shape 在官方API介绍中: ShapeDrawable:This object can be defined in an XML file with the <shape& ...