【fjwc2015】k个串 kstring

【题目描述】

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

兔子们想知道,在这个数字序列所有连续的子串中,按照以上方式统计其所有数字之和,第k大的和是多少。

【输入格式】

第一行,两个整数n和k,分别表示长度为n的数字序列和想要统计的第k大的和

接下里一行n个数a_i,表示这个数字序列

【输出格式】

一行一个整数,表示第k大的和

【样例输入】

7 5

3 -2 1 2 2 1 3 -2

【样例输出】

4

【数据范围】

对于20%的数据,1 <= n <= 2000

对于另外20%的数据,0 <= a_i <= 10^9

对于100%的数据,1 <= n <= 100000, 1 <= k <= 200000, 0 <= |a_i| <= 10^9

数据保证存在第k大的和

题解:

  理解要紧,很简单的。

  一开始以为没有地方可以提交,结果发现bzoj上就有,

  可以rt[i]表示以i为左端点的区间。

  nxt[i]表示a[i]下一次出现的位置。

  发现rt[i]对于rt[i-1],发现就是在i-----nxt[i]-1这些位置都减去a[i],

  然后,然后对于i这个位置需要变为-inf,因为无法取到。

  然后先建辅助树rt[0],即永久性flag标记打上去的区间修改,然后再以-inf,那个位置再建出

  rt[i]即可,然后进行k次操作,用堆来维护即可。

 #include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<map>
#include<queue> #define lson tr[p].ls
#define rson tr[p].rs
#define N 100007
#define ll long long
using namespace std;
const ll inf=;
inline ll read()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
} ll n,k,sz;
ll a[N],id[N],b[N],rt[N*],nxt[N];
map<ll,ll>p;
struct Node
{
ll ls,rs,mx,flag,tag;
}tr[N*];
struct Date
{
ll num,wei,rt;
friend bool operator < (Date x,Date y)
{
return x.num<y.num;
}
};
priority_queue<Date>q; bool cmp(ll x,ll y)
{
if (a[x]==a[y]) return x<y;
else return a[x]<a[y];
}
inline void update(ll p)
{
if (tr[lson].mx+tr[lson].tag>tr[rson].mx+tr[rson].tag) tr[p].mx=tr[lson].mx+tr[lson].tag,tr[p].flag=tr[lson].flag;
else tr[p].mx=tr[rson].mx+tr[rson].tag,tr[p].flag=tr[rson].flag;
}
void build(ll &p,ll l,ll r)
{
p=++sz;
if (l==r)
{
tr[p].mx=b[l];
tr[p].flag=l;
return;
}
ll mid=(l+r)>>;
build(tr[p].ls,l,mid),build(tr[p].rs,mid+,r);
update(p);
}
void build_new(ll yl,ll &xz,ll l,ll r,ll x,ll y,ll z)
{
xz=++sz,tr[xz]=tr[yl];
if (l==x&&r==y)
{
tr[xz].tag+=z;
return;
}
//标记永久化。
ll mid=(l+r)>>;
if (y<=mid) build_new(tr[yl].ls,tr[xz].ls,l,mid,x,y,z);
else if (x>mid) build_new(tr[yl].rs,tr[xz].rs,mid+,r,x,y,z);
else build_new(tr[yl].ls,tr[xz].ls,l,mid,x,mid,z),build_new(tr[yl].rs,tr[xz].rs,mid+,r,mid+,y,z);
update(xz);
}
int main()
{
freopen("kstring.in","r",stdin);
freopen("kstring.out","w",stdout); n=read(),k=read();
for (ll i=;i<=n;i++)
a[i]=read(),id[i]=i;
sort(id+,id+n+,cmp);
a[]=-inf;
for (ll i=;i<=n;i++)
if (a[id[i]]!=a[id[i-]]) b[id[i]]=a[id[i]];
for (ll i=;i<=n;i++) b[i]+=b[i-];
build(rt[],,n);
for (ll i=n;i>=;i--)
{
if (!p[a[i]]) nxt[i]=n+;
else nxt[i]=p[a[i]];
p[a[i]]=i;
}
for (ll i=;i<=n;i++)
{
if (i>nxt[i-]-) build_new(rt[i-],rt[],,n,,n,);
else build_new(rt[i-],rt[],,n,i,nxt[i-]-,-a[i-]);
build_new(rt[],rt[i],,n,i-,i-,-inf);
}
for (ll i=;i<=n;i++)
q.push((Date){tr[rt[i]].mx+tr[rt[i]].tag,tr[rt[i]].flag,i});
for(ll i=;i<k;i++)
{
Date now=q.top();q.pop();
build_new(rt[now.rt],rt[n+i],,n,now.wei,now.wei,-inf);
q.push((Date){tr[rt[n+i]].mx,tr[rt[n+i]].flag,i+n});
}
Date now=q.top();
printf("%lld\n",now.num);
}

  

bzoj4504 k个串 kstring 可持久化线段树 (标记永久化)的更多相关文章

  1. BZOJ4785 [Zjoi2017]树状数组 【二维线段树 + 标记永久化】

    题目链接 BZOJ4785 题解 肝了一个下午QAQ没写过二维线段树还是很难受 首先题目中的树状数组实际维护的是后缀和,这一点凭分析或经验或手模观察可以得出 在\(\mod 2\)意义下,我们实际求出 ...

  2. Codeforces 258E - Little Elephant and Tree(根号暴力/线段树+标记永久化/主席树+标记永久化/普通线段树/可撤销线段树,hot tea)

    Codeforces 题目传送门 & 洛谷题目传送门 yyq:"hot tea 不常有,做过了就不能再错过了" 似乎这是半年前某场 hb 模拟赛的 T2?当时 ycx.ym ...

  3. 51Nod 1175 区间中第K大的数 (可持久化线段树+离散)

    1175 区间中第K大的数 基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题   一个长度为N的整数序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有 ...

  4. 【XSY2720】区间第k小 整体二分 可持久化线段树

    题目描述 给你你个序列,每次求区间第\(k\)小的数. 本题中,如果一个数在询问区间中出现了超过\(w\)次,那么就把这个数视为\(n\). 强制在线. \(n\leq 100000,a_i<n ...

  5. P3332 [ZJOI2013]K大数查询(线段树套线段树+标记永久化)

    P3332 [ZJOI2013]K大数查询 权值线段树套区间线段树 把插入的值离散化一下开个线段树 蓝后每个节点开个线段树,维护一下每个数出现的区间和次数 为了防止MLE动态开点就好辣 重点是标记永久 ...

  6. 【BZOJ3110】K大数查询(权值线段树套线段树+标记永久化,整体二分)

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

  7. bzoj 1513 POI2006 Tet-Tetris 3D 二维线段树+标记永久化

    1511: [POI2006]OKR-Periods of Words Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 351  Solved: 220[S ...

  8. 洛谷P3437 [POI2006]TET-Tetris 3D(二维线段树 标记永久化)

    题意 题目链接 Sol 二维线段树空间复杂度是多少啊qwqqq 为啥这题全网空间都是\(n^2\)还有人硬要说是\(nlog^2n\)呀.. 对于这题来说,因为有修改操作,我们需要在外层线段树上也打标 ...

  9. HFUUOJ1024 动态开点线段树+标记永久化

    题意 分析 动态加点线段树,标记永久化好写常数小 Code #include<bits/stdc++.h> #define fi first #define se second #defi ...

随机推荐

  1. 转-AFNetwork 作用和用法详解

    来自:http://www.maxiaoguo.com/clothes/269.html AFNetworking是一个轻量级的iOS网络通信类库.它建立在NSURLConnection和NSOper ...

  2. Codeforces Round #235 (Div. 2) D (dp)

    以为是组合,后来看着像数位dp,又不知道怎么让它不重复用..然后就没思路 了. 其实状压就可以了 状压是可以确定一个数的使用顺序的 利用01也可以确定所有的数的使用以及不重复 dp[i+1<&l ...

  3. 关于python2.7的md5加密遇到的问题(TypeError: Unicode-objects must be encoded before hashing)

    https://blog.csdn.net/u012087740/article/details/48439559 import hashlib import sys def md5s(): m=ha ...

  4. SSM学习

    一.https://www.cnblogs.com/zyw-205520/p/4771253.html 二.https://blog.csdn.net/dwhdome/article/details/ ...

  5. 解决 图片在div中等比例缩放问题 (未解决:图片比例小于盒子模型时不会自动填充)

    如题,该方案仅支持对图片等比例缩放.本文附件地址:https://files.cnblogs.com/files/john69-/background-Img.rar <!DOCTYPE htm ...

  6. Vue.js学习笔记--1.基础HTML和JS属性的使用

    整理自官网教程 -- https://cn.vuejs.org/ 1. 在HTML文件底部引入Vue <script src="https://cdn.jsdelivr.net/npm ...

  7. 关于 Oracle 11g r2 Enterprise Manager (EM) 在windows环境无法启动的解决办法

    正确的解决办法是在安装的时候使用emca正确安装 如果已经安装过Enterprise Manager: 请用是如下命令卸载后重装 emca -deconfig dbcontrol db emca -r ...

  8. InChatter系统之服务端的Windows服务寄宿方式(三)

    为了部署的方便,我们开发Windows服务的服务寄宿程序,这样我们的服务便可以作为系统服务,随着系统的启动和关闭而启动和关闭,而避免了其他的设置,同时在服务的终止时(如系统关闭等)能及时处理服务的关闭 ...

  9. SQL Server xtype的介绍

    sysobjects 表 在数据库内创建的每个对象(约束.默认值.日志.规则.存储过程等)在表中占一行.只有在 tempdb 内,每个临时对象才在该表中占一行. 列名 数据类型 描述 name sys ...

  10. 从0开始搭建SQL Server 2012 AlwaysOn 第一篇(AD域与DNS)

    随着业务发展,公司需要提高数据安全与性能需求,所以需要对新技术预研(先采坑),做技术积累: 了解相关AlwaysOn 故障转移集群(热备),数据路由(ICX),Moebius(莫比斯数据路由) 决定测 ...