BZOJ 4505 K个串 主席树标记永久化
来源:互联网 发布:淘宝美版ac68u 编辑:程序博客网 时间:2024/06/15 17:17
Description
兔子们在玩
兔子们想知道,在这个数字序列所有连续的子串中,按照以上方式统计其所有数字之和,第
Input
第一行,两个整数
接下里一行
Output
一行一个整数,表示第k大的和
Sample Input
7 5
3 -2 1 2 2 1 3 -2
Sample Output
4
HINT
Solution:
初看这道题我也很懵逼啊,始终在
首先我们预处理出当前数前一个与之相同的数的位置,这里我们记一个
然后我们考虑建主席树,对于新建的一颗树实在其上颗树的
这是我们考虑如何求第
Code :
#include <cstdio>#include <cstdlib>#include <cstring>#include <string>#include <algorithm>#include <iostream>#include <cmath>#include <ctime>#include <map>#include <queue>#define LL long long#define mp make_pairusing namespace std;inline int read() { int i = 0, f = 1; char ch = getchar(); while(!isdigit(ch)) { if(ch == '-') f = -1; ch = getchar(); } while(isdigit(ch)) { i = (i << 3) + (i << 1) + ch - '0'; ch = getchar(); } return i * f;}const int MAXN = 1e5 + 5;struct point { int pos, l, r, x; LL sum; point() {} point(int ex, int epos, int el, int er, LL esum) : x(ex), pos(epos), l(el), r(er), sum(esum) {} inline bool operator <(const point & a) const { return sum < a.sum; }};struct node { LL mx, lazy; node *lc, *rc; int pos;} *root[MAXN], pool[MAXN * 40], *cur = pool;int num[MAXN];inline void build(int l, int r, node *&rt) { rt = cur++, rt->pos = l; if(l == r) return; register int mid = l + r >> 1; build(l, mid, rt->lc), build(mid + 1, r, rt->rc);}inline void get(node *a, node *b) { a->lc = b->lc, a->rc = b->rc, a->lazy = b->lazy;}inline void insert(node *&rt, node *pre, int l, int r, int s, int t, int d) { rt = cur++, get(rt, pre); if(s <= l && r <= t) { rt->mx = pre->mx + d, rt->lazy += d, rt->pos = pre->pos; return ; } register int mid = l + r >> 1; if(s <= mid) insert(rt->lc, pre->lc, l, mid, s, t, d); if(mid < t) insert(rt->rc, pre->rc, mid + 1, r, s, t, d); if(rt->lc->mx >= rt->rc->mx) { rt->mx = rt->lc->mx + rt->lazy, rt->pos = rt->lc->pos; } else { rt->mx = rt->rc->mx + rt->lazy, rt->pos = rt->rc->pos; }}inline pair<int, LL> query(node *rt, int l, int r, int s, int t) { if(s <= l && r <= t) return mp(rt->pos, rt->mx); register int mid = l + r >> 1; if(t <= mid) { pair<int, LL> tmp = query(rt->lc, l, mid, s, t); tmp.second += rt->lazy; return tmp; } else if(s > mid) { pair<int, LL> tmp = query(rt->rc, mid + 1, r, s, t); tmp.second += rt->lazy; return tmp; } else { pair<int, LL> tmpl, tmpr; tmpl = query(rt->lc, l, mid, s, t); tmpr = query(rt->rc, mid + 1, r, s, t); tmpl.second += rt->lazy, tmpr.second += rt->lazy; return tmpl.second >= tmpr.second ? tmpl : tmpr; }}inline void solve() { int n = read(), k = read(); build(1, n, root[0]); priority_queue<point> q; map<int, int> pre; for(register int i = 1; i <= n; ++i) { num[i] = read(); int s = pre[num[i]] + 1, t = i, d = num[i]; insert(root[i], root[i - 1], 1, n, s, t, d); pair<int, LL> tmp = query(root[i], 1, n, 1, t); q.push(point(i, tmp.first, 1, i, tmp.second)); pre[num[i]] = i; } while(--k) { point a = q.top(); q.pop(); if(a.l < a.pos) { pair<int, LL> tmp = query(root[a.x], 1, n, a.l, a.pos - 1); q.push(point(a.x, tmp.first, a.l, a.pos - 1, tmp.second)); } if(a.r > a.pos) { pair<int, LL> tmp = query(root[a.x], 1, n, a.pos + 1, a.r); q.push(point(a.x, tmp.first, a.pos + 1, a.r, tmp.second)); } } cout<<q.top().sum;}int main() { solve();}
- BZOJ 4505 K个串 主席树标记永久化
- bzoj 4504: K个串 主席树
- [主席树套堆 区间修改 标记永久化] BZOJ 3489 A simple rmq problem
- [树链剖分 线段树 标记永久化] BZOJ 4515 [Sdoi2016]游戏
- [BZOJ4504][主席树]K个串
- BZOJ 3165: [Heoi2013]Segment 标记永久化
- bzoj 1513: [POI2006]Tet-Tetris 3D(二维线段树+标记永久化)
- BZOJ 1568 [JSOI2008]Blue Mary开公司 标记永久化线段树
- BZOJ 1568 Blue Mary开公司(线段树,标记永久化)
- BZOJ 1568: [JSOI2008]Blue Mary开公司 标记永久化
- 3110: [Zjoi2013]K大数查询 线段树套线段树 标记永久化
- [线段树 标记永久化 单调队列] BZOJ 1171 大sz的游戏 && BZOJ 2892 强袭作战
- 二维线段树+标记永久化 poj2155
- 标记永久化的线段树
- 线段树lazy标记永久化
- bzoj4034树链剖分+线段树标记永久化
- bzoj 4504: K个串
- bzoj 3932(主席树)
- 使用JAVA猜数字游戏
- RPC
- 不刷新页面的登录框(基于Thinkphp)
- 表、栈、队列联系
- 在x86汇编中使用C语言的全局变量
- BZOJ 4505 K个串 主席树标记永久化
- JS纵深学习记录
- Java中多线程通信实例:生产者消费者模式
- 对角矩阵
- -PC.CRASH.v8.0 交通事故再现软件.iso
- Some notes as a beginner.
- GitHub客户端操作1--仓库相关操作&github团队协作流程
- Tomcat部署时war和war exploded区别以及平时踩得坑
- SpringMVC定时器使用