Luogu P2617 Dynamic Rankings
带修主席树的模板,因为状态不好所以敲了很长时间,不过写完感觉能更好地理解主席树了。
核心其实就是树状数组套主席树,维护方法不再是以前的那种一步一修改,而是对于树状数组上的每一个点建立一棵权值线段树,然后一点一点地维护。这样就从朴素修改后缀所需要的每次\(O(NlogN)\)的复杂度,变成了修改\(log\)棵树所需要的\(O(Nlog^2N)\)。
几个注意事项:
本题卡常。请使用离散化后的权值进行建树。
本题卡常。不要用\(cin\)。
因为是权值线段树,所以要先删除再添加。
二分的时候也要带上全家桶(\(lowbit\)对应位)一起修改鸭~
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int INF = 1000000010;
int tot, rt[N];
int n, m, arr[N];
#define mid ((l + r) >> 1)
#define lowbit(x) (x & -x)
struct Segment_Tree {
struct Segment_Node {
int ls, rs, sz;
}t[N << 9];
Segment_Tree () {t[0].sz = 0;}
void modify (int &v, int l, int r, int w, int del) {
if (v == 0) v = ++tot;
t[v].sz += del;
if (l != r) {
if (w <= mid) {
modify (t[v].ls, l, mid + 0, w, del);
} else {
modify (t[v].rs, mid + 1, r, w, del);
}
}
}
}seg;
int cnt, sep[N << 1];
int _sep (int w) {
return lower_bound (sep + 1, sep + 1 + cnt, w) - sep;
}
void change (int pos, int val) {
for (int i = pos; i <= n; i += lowbit (i)) {
seg.modify (rt[i], 0, INF, _sep (arr[pos]), -1);
}
arr[pos] = sep[val];
for (int i = pos; i <= n; i += lowbit (i)) {
seg.modify (rt[i], 0, INF, _sep (arr[pos]), +1);
}
}
int query (int u, int v, int k) {
static int _u[30], _v[30];
// u 到 v 区间第 k 小
int l = 0, r = INF;
_u[0] = _v[0] = 0;
for (int i = u; i != 0; i -= lowbit (i)) _u[++_u[0]] = rt[i];
for (int i = v; i != 0; i -= lowbit (i)) _v[++_v[0]] = rt[i];
while (l < r) {
int lch = 0;
for (int i = 1; i <= _u[0]; ++i) lch -= seg.t[seg.t[_u[i]].ls].sz;
for (int i = 1; i <= _v[0]; ++i) lch += seg.t[seg.t[_v[i]].ls].sz;
if (k <= lch) {
for (int i = 1; i <= _u[0]; ++i) _u[i] = seg.t[_u[i]].ls;
for (int i = 1; i <= _v[0]; ++i) _v[i] = seg.t[_v[i]].ls;
r = mid;
} else {
for (int i = 1; i <= _u[0]; ++i) _u[i] = seg.t[_u[i]].rs;
for (int i = 1; i <= _v[0]; ++i) _v[i] = seg.t[_v[i]].rs;
l = mid + 1;
k -= lch;
}
}
return r;
}
struct Query {
int type, l, r, k, p, w;
}q[N];
int main () {
// cin >> n >> m;
scanf ("%d %d", &n, &m);
for (int i = 1; i <= n; ++i) {
scanf ("%d", &arr[i]);
sep[++cnt] = arr[i];
}
for (int i = 1; i <= m; ++i) {
static char opt[10];
scanf ("%s", opt);
if (opt[0] == 'Q') {
q[i].type = 0;
scanf ("%d %d %d", &q[i].l, &q[i].r, &q[i].k);
} else {
q[i].type = 1;
scanf ("%d %d", &q[i].p, &q[i].w);
sep[++cnt] = q[i].w;
}
}
sort (sep + 1, sep + 1 + cnt);
cnt = unique (sep + 1, sep + 1 + cnt) - sep - 1; INF = cnt;
for (int i = 1; i <= n; ++i) {
for (int j = i; j <= n; j += lowbit (j)) {
seg.modify (rt[j], 0, INF, _sep (arr[i]), +1);
}
}
for (int i = 1; i <= m; ++i) {
if (q[i].type == 0) {
printf ("%d\n", sep[query (q[i].l - 1, q[i].r, q[i].k)]);
} else {
change (q[i].p, _sep (q[i].w));
}
}
}
Luogu P2617 Dynamic Rankings的更多相关文章
- luogu P2617 Dynamic Rankings && bzoj 1901 (带修改区间第k大)
链接:https://www.luogu.org/problemnew/show/P2617 思路: 如果直接在主席树上修改的话,每次修改都会对后面所有的树造成影响,一次修改的复杂度就会变成 : n* ...
- luogu P2617 Dynamic Rankings(主席树)
嘟嘟嘟 一句话题意:带修改区间第\(k\)小. 不修改都会,主席树板子.但是有修改就要比较深入的理解主席树了. 众所周知,主席树中以\(i\)为根的线段树维护的是\([1, i]\)这个前缀的权值,因 ...
- luogu P2617 Dynamic Rankings(分块,n <= 1e4)
嘟嘟嘟 带修改区间第k大. 然而某谷把数据扩大到了1e5,所以用分块现在只能得50分. 分块怎么做呢?很暴力的. 基本思想还是块内有序,块外暴力统计. 对于修改,直接重排修改的数所在块,时间复杂度O( ...
- Luogu P2617 Dynamic Rankings(整体二分)
题目 动态区间第K小模板题. 一个非常可行的办法是BIT套动态开点权值SegTree,但是它跑的实在太慢了. 然后由于这题并没有强制在线,所以我们可以使用整体二分来吊打树套树. 当然如果强制在线的话就 ...
- LUOGU P2617 Dynamic Rankings(树状数组套主席树)
传送门 解题思路 动态区间第\(k\)大,树状数组套主席树模板.树状数组的每个位置的意思的是每棵主席树的根,维护的是一个前缀和.然后询问的时候\(log\)个点一起做前缀和,一起移动.时空复杂度\(O ...
- [luogu P2617] Dynamic Rankings 带修主席树
带修改的主席树,其实这种,已经不能算作主席树了,因为这个没有维护可持久化的... 主席树直接带修改的话,由于这种数据结构是可持久化的,那么要相应改动,这个节点以后所有的主席树,这样单次修改,就达到n* ...
- P2617 Dynamic Rankings(树状数组套主席树)
P2617 Dynamic Rankings 单点修改,区间查询第k大 当然是无脑树套树了~ 树状数组套主席树就好辣 #include<iostream> #include<cstd ...
- 2018.07.01洛谷P2617 Dynamic Rankings(带修主席树)
P2617 Dynamic Rankings 题目描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i ...
- 洛谷P2617 Dynamic Rankings (主席树)
洛谷P2617 Dynamic Rankings 题目描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a ...
随机推荐
- jvm相关参数
官方地址:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html#BEHHGFAE 一.查看jvm运行参数 1.查看 ...
- Lodop打印html数字间隔不一致
在font-size属性控制数字大小的时候,可能会出现数字间隔有问题,间隔不一致,可尝试用其他字体大小试试,一般字体越小,越可能出现问题. 如图,前两个打印项都是form1,样式一个是style1,一 ...
- How to write to an event log by using Visual C#
using System; using System.Diagnostics; namespace WriteToAnEventLog_csharp { /// Summary description ...
- window.onpopstate
概述 window.onpopstate是popstate事件在window对象上的事件句柄. 每当处于激活状态的历史记录条目发生变化时,popstate事件就会在对应window对象上触发. 如果当 ...
- linux查找符合条件的文件并删除
找到根目录下所有的以test开头的文件并把查找结果当做参数传给rm -rf命令进行删除: 1.find / -name “test*” |xargs rm -rf 2.find / -name “te ...
- Codeforces Round #470 Div. 1
A:暴力枚举x2的因子,由此暴力枚举x1,显然此时减去其最大质因子并+1即为最小x0. #include<iostream> #include<cstdio> #include ...
- Git神器使用相关
感谢 感谢作者的网站,本文所有的知识可以在上述网站了解到,讲的非常详细,感谢.(https://www.liaoxuefeng.com/wiki/0013739516305929606dd183612 ...
- 【XSY2721】求和 杜教筛
题目描述 设\(n=\prod a_i^{p_i}\),那么定义\(f_d(n)=\prod{(-1)^{p_i}[p_i\leq d]}\).特别的,\(f_1(n)=\mu(n)\). 给你\(n ...
- AtCoder 瞎做
目录 ARC 058 E - 和風いろはちゃん / Iroha and Haiku 题意 题解 技巧 代码 ARC 059 F - バイナリハック / Unhappy Hacking 题意 题解 技巧 ...
- 【原创】【状态压缩DP】POJ3254 Corn Fields【新手向】
一开始根本不会状压dp,上网各种找题解,但发现他们写的都很......反正我作为一个没有接触过状态压缩的,根本看不懂! 然后看了好多状态压缩的题的题解,总结了一下思路,思路很重要,有了思路转换成计算机 ...