http://www.lydsy.com/JudgeOnline/problem.php?id=1901

重新用整体二分写了一下。

整体二分的思想详见论文。

貌似带修区间k大和静态区间k大都是\(O(n\log^2n)\)。

cdq是对时间分治,整体二分是对答案分治。

对于动态区间k大怎么实现我还想了很长时间呢,感觉模板题都想这么长时间。。。

动态区间k大的关键步骤是把修改变成两个操作,删除和插入。

这样在一个分治函数内部就可以扫时间轴然后在特定权值范围内的删除和插入分别在bits上-1和+1。

相比较在线bits套主席树,离线整体二分跑得飞快。

离散化后跑得能快一点,不离散的话时间复杂度就是\(O(n\log n\log 10^9)\),离散的话时间复杂度是\(O(n\log^2n)\)。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int N = 10003; struct node {int x, y, k, op, id;} B[N << 2], q1[N << 2], q2[N << 2];
int tot = 0, a[N], n, m, bits[N << 1], top = 0, H[N << 1], cnt = 0;
int ans[N], id[N << 2], anstot = 0, que[N << 1], q1len, q2len; void add(int x, int flag) {for (; x <= n; x += (x & (-x))) bits[x] += flag;}
int sum(int x) {int ret = 0; for (; x; x -= (x & (-x))) ret += bits[x]; return ret;} void solve(int p, int q, int l, int r) {
if (p > q) return;
if (l == r) {
for (int i = p; i <= q; ++i)
if (B[i].op == 3)
ans[B[i].id] = l;
return;
} int mid = (l + r) >> 1;
for (int i = p; i <= q; ++i) {
if (B[i].op != 3) {
if (B[i].y <= mid)
add(B[i].x, B[i].op);
}
else que[i] = sum(B[i].y) - sum(B[i].x - 1);
} for (int i = p; i <= q; ++i)
if (B[i].op != 3 && B[i].y <= mid) add(B[i].x, -B[i].op); q1len = q2len = 0;
for (int i = p; i <= q; ++i)
if (B[i].op != 3) {
if (B[i].y > mid) q2[++q2len] = B[i];
else q1[++q1len] = B[i];
} else {
if (que[i] >= B[i].k) q1[++q1len] = B[i];
else B[i].k -= que[i], q2[++q2len] = B[i];
} int tmp = p - 1;
for (int i = 1; i <= q1len; ++i)
B[++tmp] = q1[i];
for (int i = 1; i <= q2len; ++i)
B[++tmp] = q2[i]; tmp = p + q1len - 1;
solve(p, tmp, l, mid);
solve(tmp + 1, q, mid + 1, r);
} int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) {
scanf("%d", a + i);
B[++tot] = (node) {i, a[i], 0, 1, 0};
H[++cnt] = a[i];
} int x, y, k;
char c[2];
for (int i = 1; i <= m; ++i) {
scanf("%s", c);
if (c[0] == 'Q') {
scanf("%d%d%d", &x, &y, &k);
B[++tot] = (node) {x, y, k, 3, ++anstot};
} else {
scanf("%d%d", &x, &y);
B[++tot] = (node) {x, a[x], 0, -1, 0};
B[++tot] = (node) {x, y, 0, 1, 0};
H[++cnt] = (a[x] = y);
}
} stable_sort(H + 1, H + cnt + 1);
cnt = unique(H + 1, H + cnt + 1) - H;
for (int i = 1; i <= tot; ++i)
if (B[i].op != 3)
B[i].y = lower_bound(H + 1, H + cnt, B[i].y) - H; solve(1, tot, 1, cnt - 1); for (int i = 1; i <= anstot; ++i) printf("%d\n", H[ans[i]]);
return 0;
}

【BZOJ 1901】【ZJU 2112】Dynamic Rankings的更多相关文章

  1. 【BZOJ 1901】【Zju 2112】 Dynamic Rankings 动态K值 树状数组套主席树模板题

    达神题解传送门:http://blog.csdn.net/dad3zz/article/details/50638360 说一下我对这个模板的理解: 看到这个方法很容易不知所措,因为动态K值需要套树状 ...

  2. 【bzoj 1901】Zju2112 Dynamic Rankings

    Description 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]……a[j]中第k小的数是 ...

  3. 【BZOJ 1901】Zju2112 Dynamic Rankings &&【COGS 257】动态排名系统 树状数组套线段树

    外面是树状数组,里面是动态开点线段树,对于查询我们先把有关点找出来,然后一起在线段树上行走,这样就是单个O(log2)的了 #include <cstdio> #include <v ...

  4. 【BZOJ】【1901】【Zju2112】 Dynamic Rankings

    再填个坑. 动态维护区间第K大(带单点修改) 首先裸的区间第K大我们是用的[前缀和]思想,实现O(n)预处理,O(1)找树查询,那么如果是动态的呢?我们可以利用树状数组(BIT)的思想,进行O(log ...

  5. [BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】

    题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log^2 n). 线段树比树状数组麻 ...

  6. BZOJ 1901: Zju2112 Dynamic Rankings[带修改的主席树]【学习笔记】

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 7143  Solved: 2968[Su ...

  7. 【BZOJ】3052: [wc2013]糖果公园

    http://www.lydsy.com/JudgeOnline/problem.php?id=3052 题意:n个带颜色的点(m种),q次询问,每次询问x到y的路径上sum{w[次数]*v[颜色]} ...

  8. 【BZOJ】3319: 黑白树

    http://www.lydsy.com/JudgeOnline/problem.php?id=3319 题意:给一棵n节点的树(n<=1e6),m个操作(m<=1e6),每次操作有两种: ...

  9. 【BZOJ】3319: 黑白树(并查集+特殊的技巧/-树链剖分+线段树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3319 以为是模板题就复习了下hld............................. 然后n ...

随机推荐

  1. 【BZOJ4819】【SDOI2017】新生舞会 [费用流][分数规划]

    新生舞会 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 学校组织了一次新生舞会,Cathy ...

  2. 关于SQL注入的五大报错注入函数

    ~全部都以查user()为例子~ 1.floor()id = 1 and (select 1 from  (select count(*),concat(version(),floor(rand(0) ...

  3. js_如何优化你的代码让它更好看

    1.对于美的东西我们很难拒绝,比如美女.哈哈哈,程序员的梗. 2.所以我希望我写出来的代码也是很美观的,让人看起来会很舒服. 3.要想让你的代码简约美观,就要涉及封装,模块化了,可复用代码.vue可以 ...

  4. 数字签名算法rsa

    数字签名算法消息传递模型 由消息发送方构建密钥对,这里由甲方完成. 由消息发送方公布公钥至消息接收方,这里由甲方将公钥公布给乙方. 注意如加密算法区别,这里甲方使用私钥对数据签名,数据与签名形成一则消 ...

  5. 限制printk打印频率函数printk_ratelimit【转】

    转自:http://blog.csdn.net/lkkey80/article/details/45190095 版权声明:博文地址 http://blog.csdn.net/lkkey80?view ...

  6. 64_l2

    libcec-devel-4.0.2-3.fc26.x86_64.rpm 22-May-2017 22:13 27942 libcephfs-devel-10.2.7-2.fc26.i686.rpm ...

  7. centos6.5升级Linux内核步骤

    centos6.5升级Linux内核步骤 http://www.jianshu.com/p/c75f00182b4c 使用的操作系统是是centos6.5,按照官方的推荐的配置,把linux内核升级到 ...

  8. 集合类---set

    定义:一个不包含重复元素的collection.set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素,不保证集合里元素的顺序. 方法使用详解: 1 ...

  9. 2015多校第6场 HDU 5361 并查集,最短路

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5361 题意:有n个点1-n, 每个点到相邻点的距离是1,然后每个点可以通过花费c[i]的钱从i点走到距 ...

  10. 辨别苹果数据线真伪 苹果计算器 Dashboard 知识

    辨别苹果数据线真伪 苹果计算器 Dashboard 知识  苹果数据线真伪的最简单的辨别: 线质柔软 用数据线连接适配器(苹果自带的适配器)充电 连接手机 如果该手机数据线是假的, 在手机上会提示”该 ...