带修主席树的模板,因为状态不好所以敲了很长时间,不过写完感觉能更好地理解主席树了。

核心其实就是树状数组套主席树,维护方法不再是以前的那种一步一修改,而是对于树状数组上的每一个点建立一棵权值线段树,然后一点一点地维护。这样就从朴素修改后缀所需要的每次\(O(NlogN)\)的复杂度,变成了修改\(log\)棵树所需要的\(O(Nlog^2N)\)。

几个注意事项:

  1. 本题卡常。请使用离散化后的权值进行建树。

  2. 本题卡常。不要用\(cin\)。

  3. 因为是权值线段树,所以要先删除再添加。

  4. 二分的时候也要带上全家桶(\(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的更多相关文章

  1. luogu P2617 Dynamic Rankings && bzoj 1901 (带修改区间第k大)

    链接:https://www.luogu.org/problemnew/show/P2617 思路: 如果直接在主席树上修改的话,每次修改都会对后面所有的树造成影响,一次修改的复杂度就会变成 : n* ...

  2. luogu P2617 Dynamic Rankings(主席树)

    嘟嘟嘟 一句话题意:带修改区间第\(k\)小. 不修改都会,主席树板子.但是有修改就要比较深入的理解主席树了. 众所周知,主席树中以\(i\)为根的线段树维护的是\([1, i]\)这个前缀的权值,因 ...

  3. luogu P2617 Dynamic Rankings(分块,n <= 1e4)

    嘟嘟嘟 带修改区间第k大. 然而某谷把数据扩大到了1e5,所以用分块现在只能得50分. 分块怎么做呢?很暴力的. 基本思想还是块内有序,块外暴力统计. 对于修改,直接重排修改的数所在块,时间复杂度O( ...

  4. Luogu P2617 Dynamic Rankings(整体二分)

    题目 动态区间第K小模板题. 一个非常可行的办法是BIT套动态开点权值SegTree,但是它跑的实在太慢了. 然后由于这题并没有强制在线,所以我们可以使用整体二分来吊打树套树. 当然如果强制在线的话就 ...

  5. LUOGU P2617 Dynamic Rankings(树状数组套主席树)

    传送门 解题思路 动态区间第\(k\)大,树状数组套主席树模板.树状数组的每个位置的意思的是每棵主席树的根,维护的是一个前缀和.然后询问的时候\(log\)个点一起做前缀和,一起移动.时空复杂度\(O ...

  6. [luogu P2617] Dynamic Rankings 带修主席树

    带修改的主席树,其实这种,已经不能算作主席树了,因为这个没有维护可持久化的... 主席树直接带修改的话,由于这种数据结构是可持久化的,那么要相应改动,这个节点以后所有的主席树,这样单次修改,就达到n* ...

  7. P2617 Dynamic Rankings(树状数组套主席树)

    P2617 Dynamic Rankings 单点修改,区间查询第k大 当然是无脑树套树了~ 树状数组套主席树就好辣 #include<iostream> #include<cstd ...

  8. 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 ...

  9. 洛谷P2617 Dynamic Rankings (主席树)

    洛谷P2617 Dynamic Rankings 题目描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a ...

随机推荐

  1. oracle数据库备份和恢复

    参考地址:https://www.cnblogs.com/1175429393wljblog/p/9529334.html Oracle数据导入导出imp/exp 在cmd的dos命令提示符下执行,而 ...

  2. PHP涉及到的英文单调

    slashes [slæʃeis]:斜线 uppercase ['ʌpəˌkeɪs]:大写字母,简写uc strip [strɪp]:去掉 trim [trɪm]:整理(修剪) explode [ɪk ...

  3. SpringMVC 重定向到其他系统的页面的两种方式

    //测试重定向到另外的一个系统 @RequestMapping("/tttt") public void testRed(HttpServletResponse response) ...

  4. codeforces104A

    Blackjack CodeForces - 104A Tensor特别喜欢玩扑克,还总是爱发明一些关于扑克牌的游戏,有天他突然脑洞大开想到了这样的一个游戏: 现在有一副52张的扑克牌(没有大小王), ...

  5. 在没有 Emacs 的情况下使用 Org 模式

    导读 每到年初似乎总有这么一个疯狂的冲动来寻找提高生产率的方法.新年决心,正确地开始一年的冲动,以及“向前看”的态度都是这种冲动的表现.软件推荐通常都会选择闭源和专利软件.但这不是必须的. 这是我 2 ...

  6. linux不能上网问题

    第一种方法: 当linux不能上网,将网络配置成dhcp(注意:这里只能小写) onboot设置能yes 第二种方法: 第三种 window+r 快捷键 HKEY_LOCAL_MACHINE--> ...

  7. P1601 A+B Problem(高精)

    原题链接 https://www.luogu.org/problemnew/show/P1601 这个题提示的很清楚,并非简单的A+B,单纯的long  long型也不行(不要被样例所迷惑).因为lo ...

  8. Codeforces1073E Segment Sum 【数位DP】

    题目分析: 裸的数位DP,注意细节. #include<bits/stdc++.h> using namespace std; ; int k; ][],sz[][],cnt[][]; ] ...

  9. Matplotlib学习---用matplotlib画面积图(area chart)

    这里利用Nathan Yau所著的<鲜活的数据:数据可视化指南>一书中的数据,学习画图. 数据地址:http://book.flowingdata.com/ch05/data/us-pop ...

  10. poj 2226 Muddy Fields(水二分图)

    Rain has pummeled the cows' field, a rectangular grid of R rows and C columns (1 <= R <= 50, 1 ...