整体二分&cdq分治 ZOJ 2112 Dynamic Rankings
题目:单点更新查询区间第k大
按照主席树的思想,要主席树套树状数组。即按照每个节点建立主席树,然后利用树状数组的方法来更新维护前缀和。然而,这样的做法在实际中并不能AC,原因即卡空间。
因此我们采用一种叫做整体二分的方法。
说一下具体做法:
首先要离线处理
我们把原数列也当成单点更新的操作,而更改值我们则看成两个操作,第一个是删掉原来位置的值,第二个是把新的值放置在这个位置,这样一来我们就可以得到最长n*3的操作序列。
然后就是我们的整体二分步骤了,首先我们对答案进行二分,这时我们会获得一个mid值。此时对于某个询问,如果我们发现在区间内不大于mid的值的个数少于k的时候,我们显然要在比mid大的区间进行二分查找答案,然而我们这次的查找怎么办呢?答案就是记录下来。我们发现在比mid大的区间查找答案的时候,我们之前这次的查找必然也会对下次的查找做出同样的贡献,因此我们只要把这次查找的结果存下来,下次就可以避免重复查找。而另外一种情况,就不大于mid的值的个数大于等于k的时候,我们显然就需要在比mid小的区间进行查找啦,此时我们之前的查找信息只能作废。
据说整体二分的时间复杂度和询问的长度是线性相关的,然而我却认为是nlogn的,这里还不太懂,希望有大神解答...
ZOJ 2112 Dynamic Rankings链接如下:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2112
此题卡主席树的空间,但是用此代码结果如下:
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#define inf 1000000000 using namespace std; int T, n, m, tot, cnt;
int a[50010], ans[10010], tree[50010], cur[70010];
char str[5]; void updata(int pos, int val) {
while (pos <= n) {
tree[pos] += val;
pos += pos & (-pos);
}
} int read(int pos) {
int tmp = 0;
while (pos > 0) {
tmp += tree[pos];
pos -= pos & (-pos);
}
return tmp;
} struct N {
int l, r, k, id, cur, tp;
N() {}
N(int _l, int _r, int _k, int _id, int _cur, int _tp):
l(_l), r(_r), k(_k), id(_id), cur(_cur), tp(_tp) {}
};
N q[70010], q1[70010], q2[70010]; void ask(int fro, int las, int l, int r) {
if (fro > las) return ;
if (l == r) {
for (int i = fro; i <= las; i++) {
if (q[i].tp == 3) ans[q[i].id] = l;
}
return ;
}
int mid = (l + r) / 2;
for (int i = fro; i <= las; i++) {
if (q[i].tp == 1 && q[i].k <= mid) updata(q[i].l, 1);
else if (q[i].tp == 2 && q[i].k <= mid) updata(q[i].l, -1);
else if (q[i].tp == 3) cur[i] = read(q[i].r) - read(q[i].l - 1);
}
for (int i = fro; i <= las; i++) {
if (q[i].tp == 1 && q[i].k <= mid) updata(q[i].l, -1);
else if (q[i].tp == 2 && q[i].k <= mid) updata(q[i].l, 1);
}
int t1 = 0, t2 = 0;
for (int i = fro; i <= las; i++) {
if (q[i].tp == 3) {
if (q[i].cur + cur[i] >= q[i].k) {
q1[t1++] = q[i];
}
else {
q[i].cur += cur[i];
q2[t2++] = q[i];
}
}
else {
if (q[i].k <= mid) q1[t1++] = q[i];
else q2[t2++] = q[i];
}
}
for (int i = 0; i < t1; i++) q[fro + i] = q1[i];
for (int i = 0; i < t2; i++) q[fro + t1 + i] = q2[i];
ask(fro, fro + t1 - 1, l, mid);
ask(fro + t1, las, mid + 1, r);
} int main() {
//freopen("in.in", "r", stdin);
//freopen("out.out", "w", stdout);
scanf("%d", &T);
while (T--) {
memset(tree, 0, sizeof(tree));
scanf("%d %d", &n, &m);
tot = cnt = 0;
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
q[tot++] = N(i, i, a[i], 0, 0, 1);
}
int l, r, k;
for (int i = 0; i < m; i++) {
scanf("%s", str);
if (str[0] == 'Q') {
scanf("%d %d %d", &l, &r, &k);
q[tot++] = N(l, r, k, ++cnt, 0, 3);
}
else {
scanf("%d %d", &l, &k);
q[tot++] = N(l, l, a[l], 0, 0, 2);
q[tot++] = N(l, l, k, 0, 0, 1);
a[l] = k;
}
}
//printf("tot = %d cnt = %d\n", tot, cnt);
ask(0, tot - 1, 0, inf);
for (int i = 1; i <= cnt; i++)
printf("%d\n", ans[i]);
}
return 0;
}
最后,为神马csdn没有发首页的功能了呢,酱紫我的博客谁来看啊
整体二分&cdq分治 ZOJ 2112 Dynamic Rankings的更多相关文章
- 整体二分(SP3946 K-th Number ZOJ 2112 Dynamic Rankings)
SP3946 K-th Number (/2和>>1不一样!!) #include <algorithm> #include <bitset> #include & ...
- 主席树[可持久化线段树](hdu 2665 Kth number、SP 10628 Count on a tree、ZOJ 2112 Dynamic Rankings、codeforces 813E Army Creation、codeforces960F:Pathwalks )
在今天三黑(恶意评分刷上去的那种)两紫的智推中,突然出现了P3834 [模板]可持久化线段树 1(主席树)就突然有了不详的预感2333 果然...然后我gg了!被大佬虐了! hdu 2665 Kth ...
- ZOJ 2112 Dynamic Rankings(动态区间第 k 大+块状链表)
题目大意 给定一个数列,编号从 1 到 n,现在有 m 个操作,操作分两类: 1. 修改数列中某个位置的数的值为 val 2. 询问 [L, R] 这个区间中第 k 大的是多少 n<=50,00 ...
- ZOJ 2112 Dynamic Rankings(带修改的区间第K大,分块+二分搜索+二分答案)
Dynamic Rankings Time Limit: 10 Seconds Memory Limit: 32768 KB The Company Dynamic Rankings has ...
- 高级数据结构(树状数组套主席树):ZOJ 2112 Dynamic Rankings
Dynamic Rankings Time Limit: 10 Seconds Memory Limit: 32768 KB The Company Dynamic Rankings has ...
- BZOJ 1901 洛谷 P2617 ZOJ 2112 Dynamic Rankings
以下时空限制来自zoj Time limit 10000 ms Memory limit 32768 kB OS Linux Source Online Contest of Christopher' ...
- ZOJ 2112 Dynamic Rankings(主席树の动态kth)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2112 The Company Dynamic Rankings ...
- zoj 2112 Dynamic Rankings 动态第k大 线段树套Treap
Dynamic Rankings Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onlinejudge/show ...
- ZOJ -2112 Dynamic Rankings 主席树 待修改的区间第K大
Dynamic Rankings 带修改的区间第K大其实就是先和静态区间第K大的操作一样.先建立一颗主席树, 然后再在树状数组的每一个节点开线段树(其实也是主席树,共用节点), 每次修改的时候都按照树 ...
随机推荐
- 【转载】linux下如何使用sftp命令
原文地址:http://www.cnblogs.com/chen1987lei/archive/2010/11/26/1888391.html sftp 是一个交互式文件传输程式.它类似于 ftp, ...
- Django-DRF组件学习-视图学习
1.请求与响应 drf除了在数据序列化部分简写代码以外,还在视图中提供了简写操作.所以在django原有的django.views.View类基础上,drf封装了多个子类出来提供给我们使用. Djan ...
- 【Linux开发】OpenCV在ARM-linux上的移植过程遇到的问题1---cvNamedWindow调用报错的问题
问题描述: 这个实际上是最后一部的问题,将生成的共享库文件放入到了/usr/local/opencv-arm/lib下,并且设置了LD_LIBRARY_PATH中为/usr/local/opencv- ...
- Linux-定时任务-打包与压缩
figure:first-child { margin-top: -20px; } #write ol, #write ul { position: relative; } img { max-wid ...
- spring maven依赖
图解spring容器 核心容器(core container) spring-core 这个jar 文件包含Spring 框架基本的核心工具类.Spring 其它组件要都要使用到这个包里的类,是其它组 ...
- SQL Server之索引解析(一)
SQL Server之索引解析(一) 1.写在前面 微软专门给出SQL Server设计思路及实现路线,从7大体系结构阐述是如何实现,通过了解这些,我们就可以总结出数据库设计原则.编程中sql写法 ...
- [LeetCode] 108. 将有序数组转换为二叉搜索树
题目链接 : https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/ 题目描述: 将一个按照升序排列的 ...
- 列表and元组操作
一.列表 列表是我们以后比较常用的数据类型之一,通过列表我们可以实现对数据的存储.修改等操作. 首先,我们看一下列表的定义: 有了列表以后,我们可以通过下标来访问列表中的元素.注意:下表是从0开始的 ...
- Django、Flask、Tornado的区别?
Django:Python 界最全能的 web 开发框架,battery-include 各种功能完备,可维护性和开发速度一级棒.常有人说 Django 慢,其实主要慢在 Django ORM 与数据 ...
- 如何使用js在移动端和PC端居中
在手机移动端和PC端控制居中是一个很蛋痛的问题,因为屏幕宽度在变化,所以就不要写死样式,那么我想用JS来控制,灵活的控制宽度,需要注意这三个时候: (1)首先需要在页面刚加载的时候就调用此函数, (2 ...
