整体二分&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大的操作一样.先建立一颗主席树, 然后再在树状数组的每一个节点开线段树(其实也是主席树,共用节点), 每次修改的时候都按照树 ...
随机推荐
- Java中字母大小写的转换
例:String str = "AbC"; 把字符串所有字母变成小写: System.out.println(str.toLowerCase()); 把字符串所有字母大写: Sys ...
- 【Qt笔记】QAction与QToolButton的关联
QAction可以理解为一个动作数据,包含了这个同坐相关的图标.文本.是否可用等数据和状态,以及连接对应的槽函数,用于执行这个动作. QToolButton则可以使用QAction对象作为后端,显示这 ...
- Ubuntu终端路径和文件夹相互切换
一. 环境配置 1. 打开终端输入安装命令 sudo apt-get install nautilus-open-terminal 2. 重新加载文件管理器 nautilus -q 3. 重启电脑 s ...
- 网络 osi七层协议
一 互联网的本质 咱们先不说互联网是如何通信的(发送数据,文件等),先用一个经典的例子,给大家说明什么是互联网通信. 现在追溯到八九十年代,当时电话刚刚兴起,还没有手机的概念,只是有线电话,那么此时你 ...
- Python 入门之Python简介
Python 入门之Python简介 1.Python简介: (1) Python的出生: python的创始人为吉多·范罗苏姆(Guido van Rossum)(中文名字:龟叔).1989年的 ...
- UDP即时小通信
package 第十二章; import java.io.IOException; import java.net.*; public class UDPServer { /*** * * @para ...
- python 框架
支持异步的 python web 框架 tornado 轻量级 flask 框架 flask中文文档 import base64 import random import io import time ...
- [IIS]修改MaxFieldLength与MaxRequestBytes彻底解决Request Too Long的问题
当 IIS7/7.5 收到的请求头的长度超过16K(默认值),就会引发"Bad Request - Request Too Long. HTTP Error 400. The size of ...
- 执行rpm -ivh 时报错:error rpmdb BDB0113 Threadprocess 11690140458095421504 failed
执行rpm -ivh 时报错:error rpmdb BDB0113 Threadprocess 11690140458095421504 failed 1.具体报错如下: [root@heyong ...
- 学习R的悬疑录(不定期更新)
在使用caret包建模时候,没有导入机器学习包,如rpart.randomForest等,并不会对结果有影响.不知道是不是caret包内置了机器学习模块. # 加载r包 library(data.ta ...
