整体二分&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大的操作一样.先建立一颗主席树, 然后再在树状数组的每一个节点开线段树(其实也是主席树,共用节点), 每次修改的时候都按照树 ...
随机推荐
- 应用安全 - CMS - PHPCMS漏洞汇总
CVE-2011-0644 Date: 2011.1 类型: /flash_upload.php SQL注入 影响版本:phpCMS 2008 V2 PHPCMS PHPCMS通杀XSS 在我要报错功 ...
- 【Qt开发】QT中显示图像数据
一般图像数据都是以RGBRGBRGB--字节流的方式(解码完成后的原始图像流),我说成字节流,那就表明R,G,B的值各占一个字节,在编程时表示的就是unsigned char * data. 我们先来 ...
- 简述Vue的实例属性、实例方法
1.实例属性 组件树访问 $parent -----> 用来访问当前组件实例的父实例: $root -----> 用来访问当前组件树的根实例,如果当前组件没有父实例,则$root表示当前组 ...
- 【Python基础】_2 Python基本语法与常识(迭代优化中...)
2 Python的基本语法 为了保证Python解释器能顺利编译所编写的代码,也为了程序员对自己和别人所编写的程序易于阅读.维护,对编程语言的语法做一些基本约定是非常必要的. 2.1 编程方式 2.1 ...
- 基于 @Scheduled 注解的 ----定时任务
最常用的方法@Scheduled 注解表示起开定时任务 依赖 <dependencies> <dependency> <groupId>org.springfram ...
- 命令行模式和Python交互模式的区别
1.命令行模式: 在Windows开始菜单选择“命令提示符”,就进入到命令行模式,它的提示符类似C:\Users\>: 2.python交互模式 在命令行模式下敲命令python,就看到类似如下 ...
- net 架构师-数据库-sql server-002-工具
本章讲述的工具包括: SQL Server 联机丛书 SQL Server配置管理器 SQL Server Management Studio SQL Server Business Intellig ...
- P1168 中位数 堆
题目描述 给出一个长度为NN的非负整数序列A_iAi,对于所有1 ≤ k ≤ (N + 1) / 21≤k≤(N+1)/2,输出A_1, A_3, …, A_{2k - 1}A1,A3,…,A2 ...
- Scrapy 教程(八)-分布式爬虫
scrapy 本身并不是一个分布式框架,而 Scrapy-redis 库使得分布式成为可能: Scrapy-redis 并没有重构框架,而是基于redis数据库重写了框架的某些组件. 分布式框架要解决 ...
- HNUSTOJ 1604:Operations
1604: Operations 时间限制: 2 Sec 内存限制: 128 MB 提交: 313 解决: 97 [提交][状态][讨论版] 题目描述 You can perform the fo ...
